程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Rapi

編輯:.NET實例教程
本頁內容

引言 SMARTPHONE SDK API 庫 管理設備中的目錄文件 取系統信息 遠程操作電話和短信功能

    Windows Mobile日益成熟,開發者隊伍也越來越壯大。作為一個10年的計算機熱愛者和程序員,我也經受不住新技術的誘惑,倒騰起Mobile這個玩具。Mobile和Windows的血緣關系決定了它在Windows程序員中的受歡迎程度,在網絡上隨便搜索一下,關於Mobile應用、開發的文章數不勝數。可是對於計劃開發一款全能的Desktop<=>Device同步管理程序的我來說,

歡迎光臨學網,收藏本篇文章 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15]

$False$

卻發現資源少得可憐——僅僅在MSDN和兩個國外的Developer網站上發現了一點資料。現在我仍然在搜索學習中,在這裡把我迄今掌握的一點心得寫出來,希望能起到拋磚引玉的功效。另請各位高手指正。

    Mobile的開發資源很繁雜,很多人常常弄不清究竟要安裝哪些工具才能搭建出合適的開發環境。但是我相信Microsoft SMARTPHONE 2003 SDK和Microsoft POCKETPC 2003 SDK是所有的人都知道的,它們分別為SmartPhone和PocketPC提供了必不可少的支持。兄弟我至今沒有做出什麼成績,囊中羞澀,好容易攢了台SmartPhone,今天就已Microsoft SMARTPHONE 2003 SDK為例吧。

    SMARTPHONE SDK包含了大量的API,列表如下(選自SDK文檔,本人翻譯):

Smartphone API Description ActiveSync 創建移動應用程序安裝和配置,同步服務模塊,過濾器和協助訪問ActiveSync服務的應用。 Bluetooth API 創建支持藍牙設備的Mobile應用程序,比如耳機,打印機和其他移動設備。 CE Messaging (CEMAPI) 創建messaging applications Configuration Service Providers 創建可配置各種CSPs(Configuration Service Providers)的應用 Connection Manager 文章整理:學網 http://www.xue5.com (本站) [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15]

創建可自動管理移動設備網絡連接的應用 Control API 在你的移動應用程序中使用Smartphone控件 Device Management API 創建可遠程訪問移動設備配置管理的應用程序 Game API (GAPI) 創建高性能的實時游戲 Home Screen API 創建用戶界面插件 Html Control 創建可顯示Html文本和嵌入圖片,解析XML和綁定URL到別名的應用程序 MIDI 創建可播放MIDI文件的應用程序 Object Exchange (OBEX) 創建對象交換應用,允許移動設備自由的通過無線交換數據 Pocket Outlook Object Model (POOM) API 創建可操作收件箱部件(聯系人,日歷和任務)的移動應用程序 Projects Control 學網,點擊這裡查看更多文章教程 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15]

">創建可以和Projects Control交互的應用 Remote API (RAPI) 創建可以同步或控制移動設備的桌面應用程序 Speech Recognizer 為應用程序增加語音識別功能(比如語音撥號) Telephony 創建支持電話和短信的應用程序 User Interface 管理輸入面板,增加用戶界面元素到你的移動應用程序 Vibrate API 為你的移動應用程序增加震動特性 Voice Recorder Control 創建移動數字錄音程序 Windows User Interface Controls 創建將移動擴展合並到標准Microsoft® Windows® CE用戶界面控件的應用

    要創建Desktop<=>Device的桌面同步管理程序,主要就依靠SDK API中的Remote API(RAPI)。RAPI 庫由一組函數組成,這些函數可用於通過桌面應用程序管理設備,包括設備的目錄文件、設備的注冊表和系統信息。廢話不多說,我們先來看看如何管理設備中的目錄文件

    RAPI提供了一組文件管理的方法(不完全列表,詳見SDK文檔。選自SDK文檔,本人翻譯):

歡迎光臨學網,收藏本篇文章 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15]

Function Description CeCopyFile 復制文件 CeCreateDirectory 創建目錄 CeCreateFile 創建,打開文件、管道、通訊資源、磁盤設備或者控制台。返回一個句柄用來訪問對象。 CeDeleteFile 刪除文件 CeFindAllFiles 從指定的Windows CE目錄中獲取所有文件和目錄的信息,並且復制到一個包含CE_FIND_DATA結構的數組中 CeFindFirstFile 在目錄中查找匹配給定文件名的一個文件 CeFindClose 關閉指定的查找句柄,CeFindFirstFileCeFindNextFile 函數用這個句柄查找文件 CeFindNextFile 學網,收藏本篇文章 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15]

"tab" width="404">從上一次訪問的CeFindFirstFile繼續查找文件 CeGetFileAttributes 返回指定文件或目錄的屬性 CeGetFileSize 獲取指定文件的字節大小 CeGetFileTime 獲取文件創建日期時間,最後訪問日期時間和最後修改日期時間 CeMoveFile 移動(重命名)一個文件或者目錄 CeReadFile 從文件指針處讀取文件數據 CeWriteFile 從文件指針處寫入文件數據

    首先要說明的是,任何RAPI操作都需要首先初始化與設備的連接:

Function Description CeRapiInit (RAPI) 創建Windows CE remote application-programming interface (RAPI). 文章整理:學網 http://www.xue5.com (本站) [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15]

[C#.Net]
 
using System;using System.Runtime.InteropServices;
public class RAPI{	public void RapiInit() 	{		int ret = CeRapiInit();		if( ret != 0)		{			// 連接失敗,獲取失敗代碼			int e = CeRapiGetError();			// 拋出異常			Marshal.ThrowExceptionForHR(ret);		}		// 連接成功		// To Do	}	[DllImport("rapi.dll", CharSet=CharSet.Unicode)]	internal static extern int CeRapiGetError();	[DllImport("rapi.dll", CharSet=CharSet.Unicode)]	internal static extern int CeRapiInit();}

 

    連接建立後,就可以進行文件操作了。看一個將文件復制到設備的例子:

[C#.Net]
using System;using System.Runtime.InteropServices;using System.IO;
public class RAPI{	private const uint GENERIC_WRITE = 0x40000000; 	// 設置讀寫權限	private const short CREATE_NEW = 1; 			// 創建新文件	private const short FILE_ATTRIBUTE_NORMAL = 0x80; 	// 設置文件屬性	private const short INVALID_HANDLE_VALUE = -1; 	// 錯誤句柄	IntPtr remoteFile = IntPtr.Zero;	String LocalFileName = @"c:\test.txt// 本地計算機文件名 String RemoteFileName = @"\My Documents\test.txt"; // 遠程設備文件名 byte[] buffer = new byte[0x1000]; // 傳輸緩沖區定義為4k FileStream localFile; int bytesread = 0; int byteswritten = 0; int 歡迎光臨學網,點擊這裡查看更多文章教程 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] 

filepos = 0; public RapiFile() { // 創建遠程文件 remoteFile = CeCreateFile(RemoteFileName, GENERIC_WRITE, 0, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); // 檢查文件是否創建成功 if ((int)remoteFile == INVALID_HANDLE_VALUE) { throw new Exception("Could not create remote file"); } // 打開本地文件 localFile = new FileStream(LocalFileName, FileMode.Open); // 讀取4K字節 bytesread = localFile.Read(buffer, filepos, buffer.Length); while(bytesread > 0) { // 移動文件指針到已讀取的位置 filepos += bytesread; // 寫緩沖區數據到遠程設備文件 if(! Convert.ToBoolean(CeWriteFile(remoteFile, buffer, bytesread, ref byteswritten, 0))) { // 檢查是否成功,不成功關閉文件句柄,拋出異常 CeCloseHandle(remoteFile); throw new Exception("Could not write to remote file"); } try { // 重新填充本地緩沖區 bytesread = localFile.Read(buffer, 0, buffer.Length); } catch(Exception) { bytesread = 0; } } // 關閉本地文件 localFile.Close(); // 關閉遠程文件 CeCloseHandle(remoteFile); }

	// 聲明要引用的API	[DllImport("rapi.dll", CharSet=CharSet.Unicode)]	internal static extern int CeCloseHandle(IntPtr hObject); 	[DllImport("rapi.dll", CharSet=CharSet.Unicode)]	internal static extern int CeWriteFile(IntPtr hFile, byte[] lpBuffer, 		int nNumberOfbytesToWrite, ref int lpNumberOfbytesWritten, int lpOverlapped);	[DllImport("rapi.dll", CharSet=CharSet.Unicode, SetLastError=true)]	internal static extern IntPtr CeCreateFile(		string lpFileName, 		uint dwDesiredAccess,		int dwShareMode,		int lpSecurityAttributes,		int dwCreationDisposition,		int dwFlagsAndAttributes,		int hTemplateFile);}
 

    操作完畢後在合適的時候需要斷開RAPI連接,使用如下函數(選自SDK文檔,本人翻譯):

Function Description 歡迎光臨學網,收藏本篇文章 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15]

CeRapiUninit (RAPI) 銷毀Windows CE remote application-programming interface (RAPI).

[C#.Net]
using System;using System.Runtime.InteropServices;public class RAPIUninit
{ public RAPIUninit() { CeRapiUninit(); } // 聲明要引用的API [DllImport("rapi.dll", CharSet=CharSet.Unicode)] internal static extern int CeRapiUninit();}
 

    文件操作的函數有很多,基本思路都是一樣的,在這裡就不一一舉例了。請注意文件句柄使用以後一定要釋放。

    我們再看一個取系統信息的例子,RAPI提供了一些取系統信息的函數(選自SDK文檔,本人翻譯):

Function Description CeGetSystemInfo 返回當前系統信息 CeGetSystemMetrics 獲取Windows元素的尺寸和系統設置 CeGetVersionEx 獲取當前運行的操作系統版本的擴展信息 文章整理:學網 http://www.xue5.com (本站) [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15]

CeGetSystemPowerStatusEx 獲取電池狀態 CeGlobalMemoryStatus 獲取系統物理內存和虛擬內存信息 CeGetStoreInformation 獲取存儲器信息並填入STORE_INFORMATION結構

[C#.Net]
public class RAPI{	SYSTEM_INFO si;			// 系統信息	OSVERSIONINFO versionInfo;		// 版本信息	SYSTEM_POWER_STATUS_EX PowerStatus;	// 電源信息	MEMORYSTATUS ms;			// 內存信息	String info;	public void systemInfo()	{		// 檢索系統信息		try		{			CeGetSystemInfo(out si);		}		catch(Exception)		{			throw new Exception("Error retrieving system info.");		}		// 檢索設備操作系統版本號。		bool b;		versionInfo.dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFO));	// 設置為結構大小				b = CeGetVersionEx(out versionInfo);		if(!b)		{			throw new Exception("Error retrieving version information.");		}		// 檢索設備電源狀態		try		{			CeGetSystemPowerStatusEx(out PowerStatus, true); // true 表示新的電源信息,否則將從緩存中獲得 } catch(Exception) { throw new Exception("Error retrIEving system power status."); } // 檢索設備內存狀態 CeGlobalMemoryStatus( out ms ); // 設置檢索信息的格式。 info = "The connected device has an "; switch (si.wProcessorArchitecture) { case ProcessorArchitecture.Intel: info += "Intel processor.\n"; break; case ProcessorArchitecture.MIPS: info += "MIPS processor.\n"; break; case ProcessorArchitecture.ARM: info += "ARM processor.\n"; break; default: info = "unknown processor type.\n"; break; }歡迎光臨學網,點擊這裡查看更多文章教程 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] 

info += "OS version: " + versionInfo.dwMajorVersion + "." + versionInfo.dwMinorVersion + "." + versionInfo.dwBuildNumber + "\n"; if (PowerStatus.ACLineStatus == 1) { info += "On AC power:YES\n"; } else { info += "On AC power:NO \n"; } info += "Battery level: " + PowerStatus.BatteryLifePercent + "%\n"; info += "Total memory: " + String.Format("{0:###,###,###}",  ms.dwTotalPhys) + "\n"; // 顯示結果。 Console.WriteLine(info); } #region 聲明API,詳見SDK文檔 [DllImport("rapi.dll", CharSet=CharSet.Unicode, SetLastError=true)] internal static extern int CeGetSystemInfo(out SYSTEM_INFO pSI); [DllImport("rapi.dll", CharSet=CharSet.Unicode, SetLastError=true)] internal static extern bool CeGetVersionEx(out OSVERSIONINFO lpVersionInformation); [DllImport("rapi.dll", CharSet=CharSet.Unicode, SetLastError=true)] internal static extern bool CeGetSystemPowerStatusEx(out SYSTEM_POWER_STATUS_EX pStatus, bool fUpdate); [DllImport("rapi.dll", CharSet=CharSet.Unicode, SetLastError=true)] internal static extern void CeGlobalMemoryStatus(out MEMORYSTATUS msce); #endregion #region 聲明結構 /// /// 處理器架構 (CeGetSystemInfo) /// public enum ProcessorArchitecture : short { /// /// Intel /// Intel = 0, /// /// MIPS /// MIPS = 1, /// /// Alpha /// Alpha = 2, /// /// PowerPC /// PPC = 3, /// /// Hitachi SHx /// SHX = 4, /// /// ARM /// ARM = 5, /// /// IA64 /// IA64 = 6, /// /// Alpha 64 /// Alpha64 = 7, /// /// Unknown /// Unknown = -1 } /// /// 移動設備內存信息 /// [StructLayout(LayoutKind.Sequential)] public struct MEMORYSTATUS { internal uint dwLength; /// /// 當前內存占用 (%) /// public int dwMemoryLoad; /// /// 物理內存總量 /// public int dwTotalPhys; /// /// 可用物理內存 /// public int dwAvailPhys; /// /// 分頁數 /// public int dwTotalPageFile; /// /// 未分頁 /// public int dwAvailPageFile; /// /// 虛擬內存總量 /// public int dwTotalVirtual; /// /// 可用虛擬內存 /// public int dwAvailVirtual; } /// /// 移動設備電源信息 /// public struct SYSTEM_POWER_STATUS_EX { /// /// 交流電狀態 /// public byte ACLineStatus; /// /// 電池充電狀態。1 High,2 Low,4 Critical,8 Charging,128 No system battery,歡迎光臨學網,點擊這裡查看更多文章教程 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15]

255 Unknown status /// public byte BatteryFlag; /// /// 電池電量剩余百分比 /// public byte BatteryLifePercent; /// /// 保留字段,設置為0 /// internal byte Reserved1; /// /// 電池電量剩余時間(秒) /// public int BatteryLifeTime; /// /// 電池充滿電的總可用時間(秒) /// public int BatteryFullLifeTime; /// /// 保留字段,設置為0 /// internal byte Reserved2; /// /// 後備電池狀態 /// public byte BackupBatteryFlag; /// /// 後備電池剩余電量百分比 /// public byte BackupBatteryLifePercent; /// /// 保留字段,設置為0 /// internal byte Reserved3; /// /// 後備電池電量剩余時間(秒) /// public int BackupBatteryLifeTime; /// /// 後備電池充滿電的總可用時間(秒) /// public int BackupBatteryFullLifeTime; } /// /// OSVERSIONINFO platform type /// public enum PlatformType : int { /// /// Win32 on Windows CE. /// VER_PLATFORM_WIN32_CE = 3 } /// /// 操作系統版本信息 /// public struct OSVERSIONINFO { internal int dwOSVersionInfoSize; /// /// 主版本信息 /// public int dwMajorVersion; /// /// 副版本信息 /// public int dwMinorVersion; /// /// 編譯信息 /// public int dwBuildNumber; /// /// 操作系統類型 /// public PlatformType dwPlatformId; } /// /// 處理器類型 (CeGetSystemInfo) /// public enum ProcessorType : int { /// /// 386 /// PROCESSOR_INTEL_386 = 386, /// /// 486 /// PROCESSOR_INTEL_486 = 486, /// /// Pentium /// PROCESSOR_INTEL_PENTIUM = 586, /// /// P2 /// PROCESSOR_INTEL_PENTIUMII = 686, /// /// IA 64 /// PROCESSOR_INTEL_IA64 = 2200, /// /// MIPS 4000 serIEs /// PROCESSOR_MIPS_R4000        = 4000, /// /// Alpha 21064 /// PROCESSOR_ALPHA_21064       = 21064, /// /// PowerPC 403 /// PROCESSOR_PPC_403           = 403, /// /// PowerPC 601 /// PROCESSOR_PPC_601           = 601, /// /// PowerPC 603 /// PROCESSOR_PPC_603           = 603, /// /// PowerPC 604 /// PROCESSOR_PPC_604           = 604, /// /// PowerPC 620 /// PROCESSOR_PPC_620           = 620, /// /// Hitachi SH3 /// PROCESSOR_HITACHI_SH3       = 10003,歡迎光臨學網,收藏本篇文章 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15]

/// /// Hitachi SH3E /// PROCESSOR_HITACHI_SH3E      = 10004, /// /// Hitachi SH4 /// PROCESSOR_HITACHI_SH4       = 10005, /// /// Motorola 821 /// PROCESSOR_MOTOROLA_821      = 821, /// /// Hitachi SH3 /// PROCESSOR_SHx_SH3           = 103, /// /// Hitachi SH4 /// PROCESSOR_SHx_SH4           = 104, /// /// Intel StrongARM /// PROCESSOR_STRONGARM         = 2577, /// /// ARM720 /// PROCESSOR_ARM720            = 1824, /// /// ARM820 /// PROCESSOR_ARM820            = 2080, /// /// ARM920 /// PROCESSOR_ARM920            = 2336, /// /// ARM 7 /// PROCESSOR_ARM_7TDMI         = 70001 } /// /// CeGetSystemInfo的數據結構 /// public struct SYSTEM_INFO { /// /// 處理器架構 /// public ProcessorArchitecture wProcessorArchitecture; /// /// 保留 /// internal ushort wReserved; /// /// Specifies the page size and the granularity of page protection and commitment. /// public int dwPageSize; /// /// 應用程序可訪問內存地址的最小值 ///(Pointer to the lowest memory address accessible to applications /// and dynamic-link librarIEs (DLLs). ) /// public int lpMinimumApplicationAddress; /// /// 應用程序可訪問內存地址的最大值(Pointer to the highest memory address /// Accessible to applications and DLLs.) /// public int lpMaximumApplicationAddress; /// /// Specifies a mask representing the set of processors configured into /// the system. Bit 0 is processor 0; bit 31 is processor 31. /// public int dwActiveProcessorMask; /// /// 處理器數量(Specifies the number of processors in the system.) /// public int dwNumberOfProcessors; /// /// 處理器類型(Specifies the type of processor in the system.) /// public ProcessorType dwProcessorType; /// /// Specifies the granularity with which virtual memory is allocated. /// public int dwAllocationGranularity; /// /// SpecifIEs the system architecture-de文章整理:學網 http://www.xue5.com (本站) [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15]

pendent processor level. /// public short wProcessorLevel; /// /// SpecifIEs an architecture-dependent processor revision. /// public short wProcessorRevision; } #endregion}

 

    RAPI可以做的事情還有很多,比如取注冊表信息,提供對 Microsoft ActiveSync 底層功能的訪問,運行遠程應用程序,文件列表等等。只要仔細閱讀SDK文檔,相信都不是難事。

    作為Mobile設備的桌面管理程序,備份通話記錄,聯機發送短信等功能是必不可少的。在我剛發現RAPI的時候,以為和前面的例子一樣,有現成的函數可以使用。仔細研究以後才發現要復雜的多。相信這是很多朋友的希望實現的功能,所以班門弄斧,簡述如下。

    RAPI並沒有提供通話,SIM卡和短信方面的函數,它們分別包含在SmartPhone SDK的Phone API,SIM Manager和Short Message Service中。然而包含這些API的phone.dll,cellcore.dll和sms.dll都是儲存在設備上的,在Windows上運行的程序是無法調用存儲在遠程設備上的動態連接庫的。

    我們仍然需要RAPI。雖然它沒有提供直接訪問通話記錄和短信方面的操作,但是它提供了一個特殊的函數:

Function Description CeRapiInvoke 使用一種通用的機制執行遠程程序

    CeRapiInvoke的原型如下:

STDAPI_( HRESULT ) CeRapiInvoke(
    LPCWSTR pDllPath,                      // 包含AP歡迎光臨學網,點擊這裡查看更多文章教程 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15]

I的Dll文件完整路徑
    LPCWSTR pFunctionName,         // 要調用的函數名
    DWord cbInput,                           // 函數輸入緩沖區大小
    BYTE * pInput,                               // 函數輸入緩沖區指針
    DWord * pcbOutput,                  // 函數輸出緩沖區大小
    BYTE ** ppOutput,                       // 函數輸出緩沖區指針
    IRAPIStream ** ppIRAPIStream,  // 指定使用阻塞模式或流模式
    DWord dwReserved);                // 保留

    CeRapiInvoke將允許我們調用遠程設備中的任何API函數!不過不是直接調用,仍然需要對遠程API進行一些“包裝”。由於時間關系,我將在不久的將來為大家獻上關於CeRapiInvoke的詳細說明。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved