Как участвовать в Запросе WMI (WQL)

Я хочу получить порядковый номер жесткого диска начальной загрузки через запрос WQL.

Раздел начальной загрузки может быть получен с помощью следующего запроса:

SELECT * FROM Win32_DiskPartition where BootPartition=True

Порядковый номер находится в Win32_DiskDrive:

SELECT DeviceID, SerialNumber FROM Win32_DiskDrive

Win32_DiskDriveToDiskPartition имеет отображение Win32_DiskDrive кому: Win32_DiskPartition. Они отображаются Win32_DiskDrive.DeviceID кому: Win32_DiskPartition.DeviceID в Win32_DiskDriveToDiskPartition

Как я могу создать запрос WQL это внутренние объединения Win32_DiskPartition и Win32_DiskDrive? Я должен использовать Associators, или он работает с ВНУТРЕННИМ ОБЪЕДИНЕНИЕМ?

10
задан j00hi 11 July 2010 в 08:30
поделиться

2 ответа

WQL не поддерживает предложение JOIN . Как вы уже догадались, вам нужно использовать оператор ASSOCIATORS OF . Вот пример на 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 (например, Windows XP или Windows 2000), вам следует рассмотреть возможность использования API, отличных от WMI.


Изменить: (ответ на комментарий) Да, вы можете добавить вложенный запрос ASSOCIATORS OF , чтобы получить экземпляры Win32_PhysicalMedia , соответствующие Win32_DiskDrive экземпляров; что-то вроде этого:

...
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

Вы не сказали, какой язык вы используете - я думаю, в PowerShell или C # все это можно сделать более элегантно, но VBScript довольно многословен.

14
ответ дан 3 December 2019 в 16:51
поделиться

Вот код 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
10
ответ дан 3 December 2019 в 16:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: