Вызов Pinvoke для получения серийного номера Windows?

Обычный способ получить серийный номер Windows — это WMI.

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

Я не хочу использовать WMI, потому что компактный фреймворк его не поддерживает. Сборка должна работать на рабочем столе и на стороне компактного фреймворка, поэтому я не могу добавить ссылку.

Как я могу получить тот же результат, используя вызов pinvoke?


person Franz P.    schedule 02.02.2009    source источник


Ответы (2)


Вам потребуется вызвать KernelIOControl для WindowsCE.

Вот код С++, нет времени конвертировать его в С#

#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);
person Stormenet    schedule 02.02.2009

Во-первых, у вас не будет ни одного звонка, который работал бы на рабочем столе и на устройстве. Просто не произойдет. Что вы можете сделать, так это определить среду выполнения с помощью примерно такого вызова:

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 очень ограничен для приложений, и маловероятно, что вы сможете вызвать его без API-оболочки ядра или драйвера от OEM.

person ctacke    schedule 02.02.2009