Win32代码在Windows XP / 7中获取EDID

我发现这个网页,并无法得到任何有用的信息(它searchregistry的东西,但从来没有find它,并进入一个无限循环)。

由于这个关于获取显示器串行UID(“EDID信息”)的问题,我想从Win32 C代码(或C / C ++ DDK代码,或其他)而不是Linux的angular度来看相同的信息。

Solutions Collecting From Web of "Win32代码在Windows XP / 7中获取EDID"

WMI不支持Windows XP中的监视器类。 获取EDID的文档化方式是 – 仍然是 – 与安装程序API。

更长的调查和一个VC ++代码示例可在这里 。

首先,我得到了一个使用WMI Code Creator的C#版本:

try { ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\WMI", "SELECT * FROM WmiMonitorID"); foreach (ManagementObject queryObj in searcher.Get()) { Console.WriteLine("-----------------------------------"); Console.WriteLine("WmiMonitorID instance"); Console.WriteLine("-----------------------------------"); //Console.WriteLine("Active: {0}", queryObj["Active"]); Console.WriteLine("InstanceName: {0}", queryObj["InstanceName"]); dynamic snid = queryObj["SerialNumberID"]; Console.WriteLine("SerialNumberID: (length) {0}", snid.Length); Console.WriteLine("YearOfManufacture: {0}", queryObj["YearOfManufacture"]); dynamic code = queryObj["ProductCodeID"]; string pcid = ""; for (int i = 0; i < code.Length; i++) { pcid = pcid + Char.ConvertFromUtf32(code[i]); //pcid = pcid +code[i].ToString("X4"); } Console.WriteLine("ProductCodeID: " + pcid); } } catch (ManagementException e) { Console.WriteLine("An error occurred while querying for WMI data: " + e.Message); } 

下面是我找到的C ++代码,并调整了与我想读取的WmiMonitorID类(EDID结构)中的InstanceName字段一起使用。 不要忘记将setupapi.lib添加到您的链接器>其他库生成设置。

 #define _WIN32_DCOM #include <iostream> using namespace std; #include <wbemidl.h> # pragma comment(lib, "wbemuuid.lib") int EnumMonitorIDs() { ret.clear(); HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres)) { cout << "Failed to initialize COM library. Error code = 0x" << hex << hres << endl; return 1; // Program has failed. } hres = CoInitializeSecurity( NULL, -1, // COM authentication NULL, // Authentication services NULL, // Reserved RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation NULL, // Authentication info EOAC_NONE, // Additional capabilities NULL // Reserved ); if (FAILED(hres)) { cout << "Failed to initialize security. Error code = 0x" << hex << hres << endl; CoUninitialize(); return 1; } IWbemLocator *pLoc = NULL; hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc); if (FAILED(hres)) { cout << "Failed to create IWbemLocator object." << " Err code = 0x" << hex << hres << endl; CoUninitialize(); return 1; // Program has failed. } IWbemServices *pSvc = NULL; BSTR AbackB = SysAllocString(L"root\\WMI"); // Connect to the root\cimv2 namespace with // the current user and obtain pointer pSvc // to make IWbemServices calls. hres = pLoc->Connectserver( AbackB, // Object path of WMI namespace NULL, // User name. NULL = current user NULL, // User password. NULL = current 0, // Locale. NULL indicates current NULL, // Security flags. 0, // Authority (eg Kerberos) 0, // Context object &pSvc // pointer to IWbemServices proxy ); SysFreeString(AbackB); if (FAILED(hres)) { cout << "Could not connect. Error code = 0x" << hex << hres << endl; pLoc->Release(); CoUninitialize(); return 1; // Program has failed. } hres = CoSetProxyBlanket( pSvc, // Indicates the proxy to set RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx NULL, // server principal name RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx NULL, // client identity EOAC_NONE // proxy capabilities ); if (FAILED(hres)) { cout << "Could not set proxy blanket. Error code = 0x" << hex << hres << endl; pSvc->Release(); pLoc->Release(); CoUninitialize(); return 1; // Program has failed. } BSTR wql = SysAllocString(L"WQL"); BSTR select = SysAllocString(L"SELECT * FROM WmiMonitorID"); IEnumWbemClassObject* pEnumerator = NULL; hres = pSvc->ExecQuery( wql, select, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); SysFreeString(wql); SysFreeString(select); if (FAILED(hres)) { cout << "Query for operating system name failed." << " Error code = 0x" << hex << hres << endl; pSvc->Release(); pLoc->Release(); CoUninitialize(); return 1; // Program has failed. } IWbemClassObject *pclsObj = 0; ULONG uReturn = 0; while (pEnumerator) { HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if (0 == uReturn) { break; } // ok, we have the EDID record, pull some fields out of it VARIANT vtProp; hr = pclsObj->Get(L"InstanceName", 0, &vtProp, 0, 0); wcout << "----------------" << endl << "InstanceName : " << vtProp.bstrVal << endl; VariantClear(&vtProp); pclsObj->Release(); } pSvc->Release(); pLoc->Release(); pEnumerator->Release(); CoUninitialize(); return 0; } 

根据Ofek Shilon的博客文章,调整以获取所有设备ID(制造商ID +产品ID字符串):

 DISPLAY_DEVICE dd; dd.cb = sizeof(dd); DWORD dev = 0; // device index int id = 1; // monitor number, as used by Display Properties > Settings Str DeviceID; while (EnumDisplayDevices(0, dev, &dd, 0)) { DISPLAY_DEVICE ddMon; ZeroMemory(&ddMon, sizeof(ddMon)); ddMon.cb = sizeof(ddMon); DWORD devMon = 0; while (EnumDisplayDevices(dd.DeviceName, devMon, &ddMon, 0)) { DeviceID.Sprintf("%s", ddMon.DeviceID); DeviceID = DeviceID.Slice(8); if (DeviceID.Index("\\") > 0) DeviceID = DeviceID.Slice(0, DeviceID.Index("\\")); printf ("DEVICEID = %s --------\n", DeviceID.utf8()); } devMon++; ZeroMemory(&ddMon, sizeof(ddMon)); ddMon.cb = sizeof(ddMon); } ZeroMemory(&dd, sizeof(dd)); dd.cb = sizeof(dd); dev++; } 

NB Str这里是一个自定义的字符串类,但应该很容易重构使用任何东西。