2010-07-08 34 views
9

Tôi muốn lấy số sê-ri của đĩa cứng khởi động qua truy vấn WQL.Cách tham gia vào Truy vấn WMI (WQL)

Các khởi động phân vùng có thể được lấy ra bằng cách sử dụng truy vấn sau đây:

SELECT * FROM Win32_DiskPartition where BootPartition=True 

Số sê-ri là trong Win32_DiskDrive:

SELECT DeviceID, SerialNumber FROM Win32_DiskDrive 

Win32_DiskDriveToDiskPartition có các bản đồ của Win32_DiskDrive-Win32_DiskPartition. Họ được ánh xạ Win32_DiskDrive.DeviceID để Win32_DiskPartition.DeviceID trong Win32_DiskDriveToDiskPartition

Làm thế nào tôi có thể xây dựng một truy vấn WQL rằng bên tham gia Win32_DiskPartitionWin32_DiskDrive? Tôi có phải sử dụng Associators hoặc nó hoạt động với INNER JOIN không?

Trả lời

13

WQL không hỗ trợ mệnh đề JOIN. Bạn cần sử dụng câu lệnh ASSOCIATORS OF như bạn đã đoán. Dưới đây là ví dụ trong 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 

Lưu ý, tuy nhiên, thuộc tính Win32_DiskDrive.SerialNumber không khả dụng trước Windows Vista. Vì vậy, nếu bạn muốn mã của bạn hoạt động trên các phiên bản Windows cũ hơn (ví dụ: Windows XP hoặc Windows 2000), bạn nên cân nhắc sử dụng các API khác với WMI.


Edit:(trả lời bình luận) Vâng, bạn có thể thêm một ASSOCIATORS OF truy vấn lồng nhau để có được những Win32_PhysicalMedia trường hợp tương ứng với Win32_DiskDrive trường; một cái gì đó như thế này:

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

Bạn chưa nói gì ngôn ngữ mà bạn đang sử dụng - Tôi đoán trong PowerShell hoặc C# toàn bộ điều có thể thực hiện thanh lịch hơn, nhưng VBScript là khá dài dòng.

+0

Cảm ơn bạn rất nhiều! Win32_PhysicalMedia có sẵn trước Windows Vista, theo như tôi biết. Tôi có phải "tham gia" ba đối tượng WMI này thông qua các liên kết để đạt được khả năng tương thích với Windows XP không? – j00hi

+0

Bạn đã giúp tôi rất nhiều! Cảm ơn! Tôi đã viết nó trong C++, nhưng tiến trình là như nhau. Tôi sẽ đăng mã C++ của tôi, có lẽ nó có thể hữu ích cho ai đó. – j00hi

9

Đây là mã C++ thực hiện tương tự như mã VBScript do Helen đăng.

// 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 
+0

Điều thú vị là mã này tương thích với ít nhất Windows XP. Tôi đã thử nghiệm thành công mã này trên Win7 64bit, Win7 32bit và WinXP. – j00hi

Các vấn đề liên quan