2009-02-02 31 views
0

獲取Windows序列號的正常方法是WMI。Pinvoke調用獲取Windows序列號?

ManagementObjectSearcher mos = new ManagementObjectSearcher("Select * From Win32_OperatingSystem"); 
// ... 
// Select number from managementobject mo["SerialNumber"] 

我不想使用WMI,因爲緊湊型框架無法支持它。程序集必須在桌面和緊湊框架一側工作,所以我不能添加引用。

如何使用pinvoke調用獲得相同的結果?

回答

1

您需要爲WindowsCE調用KernelIOControl。

這裏的C++代碼,不必將其轉換爲C#

#include <WINIOCTL.H> 
extern "C" __declspec(dllimport) 
BOOL KernelIoControl(DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize, LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned); 
#define IOCTL_HAL_GET_DEVICEID CTL_CODE(FILE_DEVICE_HAL, 21, METHOD_BUFFERED, FILE_ANY_ACCESS) 

CString GetSerialNumberFromKernelIoControl() { 
    DWORD dwOutBytes; 
    const int nBuffSize = 4096; 
    byte arrOutBuff[nBuffSize]; 
    BOOL bRes = ::KernelIoControl(IOCTL_HAL_GET_DEVICEID, 0, 0, arrOutBuff, nBuffSize, &dwOutBytes); 
    if (bRes) { CString strDeviceInfo; for (unsigned int i = 0; i<dwOutBytes; i++) { 
     CString strNextChar; strNextChar.Format(TEXT("%02X"), arrOutBuff[i]); strDeviceInfo += strNextChar; 
    } 
    CString strDeviceId = strDeviceInfo.Mid(40,2) + strDeviceInfo.Mid(45,9) + strDeviceInfo.Mid(70,6); 
    return strDeviceId; 
    } else { 
     return _T(""); 
    } 
} 

編輯時間:(PInvoke的kernelIOControl C#)

​​
0

首先,你不將在桌面和設備上有一個單一的電話。只是不會發生。你可以做的是用這樣的調用來確定運行時環境:

if(Environment.OSVersion.Platform == PlatformID.WinCE) { ... } 

這會給你桌面和設備的分離。

然後,您必須添加設備的複雜性,並且需要了解您的目標硬件。對於Windows Mobile 5.0和更高版本,您希望調用GetDeviceUniqueID,因爲KernelIoControl調用很可能將受到保護。在Pocket PC 2003及更早版本中,KernelIoControl P/Invoke是合理的,儘管許多設備已知會呈現相同的結果,所以它不能保證獨一無二。

對於通用的Windows CE設備,它更加多樣化。沒有什麼能夠保證 平臺實現IOCTL_HAL_GET_DEVICEID,所以你會想要保護這個失敗並找到其他機制(通常OEM實現他們自己的ID API)。對於CE 6.0,KernelIoControl對應用程序的限制很大,如果沒有OEM的內核或驅動程序封裝API,則不太可能調用它。