C++ 如何加入WMI查询(WQL)
我想通过WQL查询获得引导硬盘的序列号 可以使用以下查询检索启动分区:C++ 如何加入WMI查询(WQL),c++,vbscript,wmi,wql,C++,Vbscript,Wmi,Wql,我想通过WQL查询获得引导硬盘的序列号 可以使用以下查询检索启动分区: SELECT * FROM Win32_DiskPartition where BootPartition=True 序列号位于Win32_DiskDrive中: SELECT DeviceID, SerialNumber FROM Win32_DiskDrive Win32\u DiskDrive ToDiskPartition具有Win32\u DiskDrive到Win32\u DiskPartition的映射。
SELECT * FROM Win32_DiskPartition where BootPartition=True
序列号位于Win32_DiskDrive中:
SELECT DeviceID, SerialNumber FROM Win32_DiskDrive
Win32\u DiskDrive ToDiskPartition具有Win32\u DiskDrive到Win32\u DiskPartition的映射。
它们被映射到Win32_DiskDrive.DeviceID到Win32_DiskDrive中的Win32_DiskPartition.DeviceID到DiskPartition
如何构建一个内部连接Win32_DiskPartition和Win32_DiskDrive的WQL查询?
我必须使用Associators吗?还是它与内部联接一起工作?WQL不支持JOIN子句。您需要使用您所猜测的语句关联符。以下是VBScript中的一个示例:
strComputer = "."
Set oWMI = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colPartitions = oWMI.ExecQuery( _
"SELECT * FROM Win32_DiskPartition WHERE BootPartition=True")
For Each oPartition in colPartitions
Set colDrives = oWMI.ExecQuery( _
"ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" _
& oPartition.DeviceID & "'} WHERE ResultClass=Win32_DiskDrive")
For Each oDrive in colDrives
WScript.Echo oDrive.SerialNumber
Next
Next
但是请注意,Win32_DiskDrive.SerialNumber属性在Windows Vista之前不可用。因此,如果您希望代码在较早的Windows版本上工作,例如WindowsXP或Windows 2000,则应考虑使用除了WMI以外的API。
编辑:回复评论是,您可以添加一个嵌套的查询关联器,以获取Win32\U DiskDrive实例对应的Win32\U PhysicalMedia实例;大概是这样的:
...
For Each oDrive in colDrives
Set colMedia = oWMI.ExecQuery( _
"ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" _
& oDrive.DeviceID & "'} WHERE ResultClass=Win32_PhysicalMedia")
For Each oMedia in colMedia
WScript.Echo oMedia.SerialNumber
Next
Next
你没有说你使用的语言——我想在PuxBeSk或C中,整个事情可以做得更优雅,但是VBScript非常冗长。
< P>这里是C++代码,它和海伦发布的VBScript代码一样。// Obtain the initial locator to WMI
// ...
// Connect to WMI through the IWbemLocator::ConnectServer method
// ...
// Set security levels on the proxy
// ...
wchar_t wmihddsn[256];
*wmihddsn=0;
hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT * FROM Win32_DiskPartition WHERE BootPartition=True"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
if(SUCCEEDED(hres) && pEnumerator)
{
// get the first Win32_DiskPartition
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if(SUCCEEDED(hr) && 0 != uReturn)
{
VARIANT vtProp;
wchar_t tmp[1024];
char query[1024];
// Get the value of the partition's DeviceID property
hr = pclsObj->Get(L"DeviceID", 0, &vtProp, 0, 0);
if(SUCCEEDED(hr))
{
if(vtProp.vt == VT_BSTR) {
// wcout << " SerialNumber : " << vtProp.bstrVal << endl;
wcscpy(tmp, vtProp.bstrVal);
}
VariantClear(&vtProp);
// "join" Win32_DiskPartition to Win32_DiskDrive
sprintf(query,
"ASSOCIATORS OF {Win32_DiskPartition.DeviceID='%s'} WHERE ResultClass=Win32_DiskDrive",
NarrowWcharString(tmp));
hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t(query),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator1);
if(SUCCEEDED(hres) && pEnumerator1)
{
// get the first Win32_DiskDrive
hr = pEnumerator1->Next(WBEM_INFINITE, 1, &pclsObj1, &uReturn);
if(SUCCEEDED(hr) && 0 != uReturn)
{
// Get the value of the disk-drive's DeviceID
hr = pclsObj1->Get(L"DeviceID", 0, &vtProp, 0, 0);
if(SUCCEEDED(hr))
{
if(vtProp.vt == VT_BSTR)
{
wcscpy(tmp, vtProp.bstrVal);
}
VariantClear(&vtProp);
// "join" Win32_DiskDrive to Win32_PhysicalMedia
sprintf(query,
"ASSOCIATORS OF {Win32_DiskDrive.DeviceID='%s'} WHERE ResultClass=Win32_PhysicalMedia",
NarrowWcharString(tmp));
hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t(query),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator2);
if(SUCCEEDED(hres) && pEnumerator2)
{
// get the first Win32_PhysicalMedia
hr = pEnumerator2->Next(WBEM_INFINITE, 1, &pclsObj2, &uReturn);
if(SUCCEEDED(hr) && 0 != uReturn)
{
// get the PhysicalMedia's SerialNumber
hr = pclsObj2->Get(L"SerialNumber", 0, &vtProp, 0, 0);
if(SUCCEEDED(hr))
{
if(vtProp.vt == VT_BSTR)
{
// wcout << " SerialNumber : " << vtProp.bstrVal << endl;
wcscpy(wmihddsn,vtProp.bstrVal);
}
VariantClear(&vtProp);
}
}
if(pclsObj2) pclsObj2->Release();
}
if(pEnumerator2) pEnumerator2->Release();
} // get disk-drive's DeviceID
}
if(pclsObj1) pclsObj1->Release();
}
if(pEnumerator1) pEnumerator1->Release();
} // get partition's DeviceID
}
if(pclsObj) pclsObj->Release();
} // if succeeded first query
if(pEnumerator) pEnumerator->Release();
// ...
// cleanup
非常感谢你!据我所知,Win32_PhysicalMedia在Windows Vista之前可用。我必须通过关联器加入这三个WMI对象才能与Windows XP兼容吗?你帮了我很多忙!谢谢我必须用C++编写,但是程序是一样的。我将发布我的C++代码,也许它对某些人有用。最酷的是,这个代码至少兼容WindowsXP。我在Win7 64位、Win7 32位和WinXP上成功地测试了这段代码。