Pinvoke позвонить для получения серийного номера Windows? - PullRequest
0 голосов
/ 02 февраля 2009

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

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

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

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

Ответы [ 2 ]

1 голос
/ 02 февраля 2009

Вам нужно будет запустить KernelIOControl для WindowsCE.

Вот код на 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);
0 голосов
/ 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-производители реализуют свой собственный API ID). Для CE 6.0 KernelIoControl очень ограничен для приложений, и маловероятно, что вы можете вызывать его без API-оболочки ядра или драйвера от OEM.

...