获取Windows序列号的常规方法是WMI。
ManagementObjectSearcher mos = new ManagementObjectSearcher("Select * From Win32_OperatingSystem");
// ...
// Select number from managementobject mo["SerialNumber"]
我不想使用WMI,因为紧凑的框架不支持它。程序集必须在桌面和紧凑框架端工作,所以我无法添加引用。
如何使用pinvoke调用获得相同的结果?
答案 0 :(得分: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#)
[DllImport("coredll.dll")]
public static extern bool KernelIoControl(long dwIoControlCode, IntPtr lpInBuff, long dwInBuffSize, IntPtr lpOutBuff, long dwOutBuffSize, IntPtr lpBytesReturned);
答案 1 :(得分: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,您就不可能调用它。