【问题标题】:Pinvoke call for getting the windows serial number?Pinvoke 调用获取 Windows 序列号?
【发布时间】:2009-02-02 10:07:07
【问题描述】:

获取windows序列号的正常方式是WMI。

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

我不想使用 WMI,因为紧凑的框架不支持它。该程序集必须在桌面和紧凑框架端工作,因此我无法添加参考。

如何使用 pinvoke 调用获得相同的结果?

【问题讨论】:

    标签: .net winapi compact-framework 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#)

    [DllImport("coredll.dll")]
        public static extern bool KernelIoControl(long dwIoControlCode, IntPtr lpInBuff, long dwInBuffSize, IntPtr lpOutBuff, long dwOutBuffSize, IntPtr lpBytesReturned);
    

    【讨论】:

      【解决方案2】:

      首先,您不会在桌面和设备上进行一次通话。只是不会发生。你可以做的是通过这样的调用来确定运行时环境:

      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,您不太可能调用它。

      【讨论】:

        猜你喜欢
        • 2011-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-31
        • 1970-01-01
        • 1970-01-01
        • 2011-01-04
        • 1970-01-01
        相关资源
        最近更新 更多