WMI 以不同的格式返回信息
WMI returns information in different formats
我想读取硬件配置以检查我的软件许可证是否有效。目前,我尝试使用WMI
.这在许多计算机上工作了数周,但有时,如果没有明显的原因,WMI
以不同的格式返回硬件配置。例如,主硬盘的序列号从字符转换为十六进制字符串,所有字符十六进制值按对交换。我发现不同的Windows用户类型(管理员/普通)会影响格式,但它在其他情况下也会以不同的方式发生变化,我无法弄清楚模式。
有没有人知道如何使用 WMI
可靠地检查硬件配置?或者是否可以使用 MFC
避免上述问题?
WMI确实不可靠。当您不需要它时,您应该避免使用它。
以下是没有 WMI 的一种方法:
#include <string>
#include <Dbt.h>
#include <winioctl.h>
#include <SetupAPI.h>
#pragma comment(lib, "SetupAPI.lib")
#include <initguid.h>
DWORD getDeviceNumber(HANDLE hDeviceHandle)
{
STORAGE_DEVICE_NUMBER sdn = { 0 };
sdn.DeviceNumber = -1;
DWORD dwBytesReturned = 0;
if (!DeviceIoControl(hDeviceHandle, IOCTL_STORAGE_GET_DEVICE_NUMBER, nullptr, 0, &sdn, sizeof(sdn), &dwBytesReturned, nullptr))
{
return -1; //Error
}
return sdn.DeviceNumber;
}
bool GetDeviceString(std::wstring &out)
{
wchar_t wDevicePath[] = L"\\.\@:";
wDevicePath[4] = L'C'; //Replace this with your drive-letter & adjust code (C: / D: whatever)
HANDLE deviceHandle = CreateFileW(wDevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
if (deviceHandle == INVALID_HANDLE_VALUE)
return false;
DWORD dwVolumeDeviceNumber = getDeviceNumber(deviceHandle);
CloseHandle(deviceHandle);
HDEVINFO hDevInfo = SetupDiGetClassDevsW(&GUID_DEVINTERFACE_DISK, nullptr, nullptr, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDevInfo == INVALID_HANDLE_VALUE)
return false; //Error
std::vector<BYTE> buf(1024);
PSP_DEVICE_INTERFACE_DETAIL_DATA_W psp = reinterpret_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA_W>(buf.data());
SP_DEVICE_INTERFACE_DATA spInt;
SP_DEVINFO_DATA spDev;
spInt.cbSize = sizeof(spInt);
DWORD dwIndex = 0;
while (true)
{
if (!SetupDiEnumDeviceInterfaces(hDevInfo, nullptr, &GUID_DEVINTERFACE_DISK, dwIndex, &spInt))
break;
DWORD dwSize = 0;
SetupDiGetDeviceInterfaceDetailW(hDevInfo, &spInt, nullptr, 0, &dwSize, nullptr);
if (dwSize && dwSize <= buf.size())
{
psp->cbSize = sizeof(*psp);
memset(&spDev, sizeof(spDev), 0);
spDev.cbSize = sizeof(spDev);
long res = SetupDiGetDeviceInterfaceDetailW(hDevInfo, &spInt, psp, dwSize, &dwSize, &spDev);
if (res)
{
HANDLE hDrive = CreateFileW(psp->DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
if (hDrive != INVALID_HANDLE_VALUE)
{
DWORD dwUsbDeviceNumber = getDeviceNumber(hDrive);
if (dwUsbDeviceNumber == dwVolumeDeviceNumber)
{
//Found
out = psp->DevicePath;
break;
}
}
CloseHandle(hDrive);
}
}
++dwIndex;
}
SetupDiDestroyDeviceInfoList(hDevInfo);
if (out.empty()) //Was not found
return false;
return true;
}
之后,您将获得一个大设备字符串。您可能希望从中读取所需的信息。
检查以下正则表达式以检索这些内容:
(请注意,字符串可以根据设备类型而更改,因此请对其进行测试并添加/调整正则表达式 - 这些来自 U 盘测试)
ven_([^&#]+) //Vendor String/ID
prod_([^&#]+) //Product String/ID
rev_([^&#]+) //Revision String/ID
&[^#]*#([^&#]+) //Serial String/Number
正则表达式 ?再比如:
std::wregex
(见std::basic_regex
...
std::wsmatch
(见std::match_results
...
std::wstring wsDeviceString;
if (GetDeviceString(wsDeviceString))
{
std::wregex regexSerialNumber(L"&[^#]*#([^&#]+)");
std::wsmatch match;
if (std::regex_search(wsDeviceString, match, regexSerialNumber))
std::wcout << L"Serial Number of device is: " << match[1].str() << std::endl;
}
请为您的产品提供一个许可证 =)
相关文章:
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- 你能重载对象变量名本身返回的内容吗
- 为什么 Serial.println(<char[]>);返回随机字符?
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 为什么 std::p ut_time(std::gmtime 采用 %z 格式返回 +0100 表示 UTC?
- 需要将 sprintf 格式加倍并返回太长的字符串
- 我想将字符串转换为 Json 格式并返回字符串向量作为答案
- Linux 上的 FreeImage 返回 -1 格式
- 图像的像素格式始终返回 32 位
- 'fopen'返回格式错误的'fp'
- 如何用clang格式分隔lambda的尾部返回类型
- 设置返回指向包含类的指针的函数的格式
- WMI 以不同的格式返回信息
- 导致IWICBitmapFrameEncode::SetPixelFormat返回与请求的格式不同的格式的原因
- 使clang格式允许函数在自己的行上返回类型
- 用于测试 func(args) 格式是否正确以及是否具有必需的返回类型的特征
- Visual Studio c++代码格式-返回类型+ classname::func缩进
- fmod音频.setMusicSpeed返回不支持的格式错误
- 以字符串形式返回整数值以进行日期格式设置