建立 WMI 基類

為 WMI 提供者建立新 WMI 基類的建議方式是受控物件格式 (MOF) 檔案。 您也可以使用 適用于 WMI 的 COM API來建立基類。 雖然您可以在腳本中建立基底或衍生類別,但沒有提供者將資料提供給 類別及其子類別,但類別並不實用。

本主題將討論下列各節:

使用 MOF 建立基類

WMI 類別通常依賴繼承。 建立基類之前,請先檢查分散式管理工作 (DMTF) 中可用的 Common Information Model (CIM) 類別。

如果許多衍生類別都會使用相同的屬性,請將這些屬性和方法放在基類中。 您可以在 WMI 類別中定義的屬性數目上限為 1024。

建立基類時,請觀察下列類別名稱的指導方針清單:

  • 同時使用大寫和小寫字母。

  • 以字母開始類別名稱。

  • 請勿使用前置或尾端底線。

  • 將所有剩餘的字元定義為字母、數位或底線。

  • 使用一致的命名慣例。

    雖然並非必要,但類別的良好命名慣例是由底線聯結的兩個元件。 可能的話,廠商名稱應該組成名稱的前半部,而描述性類別名稱應該是第二個部分。

注意

類別在執行提供者期間無法變更。 您必須停止活動、變更 類別,然後重新開機 Windows 管理服務。 目前無法偵測類別變更。

 

在 MOF 中,使用 class 關鍵字命名基類來建立基類,但不會指出父類別。

使用 MOF 程式碼建立基類

  1. 使用類別關鍵字搭配新 類別 的名稱,後面接著一對大括弧和分號。 在大括弧之間新增 類別的屬性和方法。 提供下列程式碼範例。

    下列程式碼範例示範如何定義基類。

    class MyClass_BaseDisk
    {
    };
    

    下列程式碼範例顯示基類的定義不正確。

    class MyClass_BaseDisk : CIM_LogicalDisk
    {
    };
    
  2. 在 class 關鍵字之前新增任何類別 限定詞 ,以修改類別的使用方式。 將限定詞放在方括弧之間。 如需修改類別之限定詞的詳細資訊,請參閱 WMI 限定詞。 使用 抽象 限定詞來指出您無法直接建立這個類別的實例。 抽象類別通常用於定義數個衍生類別將使用的屬性或方法。 如需詳細資訊,請參閱 建立衍生類別

    下列程式碼範例會將 類別定義為抽象,並定義將提供資料的提供者。 ToSubClass限定詞類別指出提供者限定詞中的資訊是由衍生類別繼承。

    [Abstract, Provider("MyProvider") : ToSubClass]
    class MyClass_BaseDisk
    {
    };
    
  3. 在屬性或方法名稱之前,于方括弧內新增 類別的屬性和方法。 如需詳細資訊,請參閱 新增屬性建立方法。 您可以使用 MOF 限定詞來修改這些屬性和方法。 如需詳細資訊,請參閱 新增限定詞

    下列程式碼範例示範如何使用 MOF 限定詞來修改屬性和方法。

    [read : ToSubClass, key : ToSubClass ] string DeviceID;
      [read : ToSubClass] uint32 State;
      [read : ToSubclass, write : ToSubClass] uint64 LimitUsers;
    
  4. 儲存副檔名為 .mof 的 MOF 檔案。

  5. 在檔案上執行 Mofcomp.exe ,以向 WMI 註冊 類別。

    mofcomp.exenewmof.mof

    如果您未使用 -N 參數或預處理器命令 #pragma 命名空間 來指定命名空間,則編譯的 MOF 類別將會儲存在存放庫中的 root\default 命名空間中。 如需詳細資訊,請參閱 mofcomp

下列程式碼範例結合了上一個程式中討論的 MOF 程式碼範例,並示範如何使用 MOF 在 root\cimv2 命名空間中建立基類。

#pragma namespace("\\\\.\\Root\\cimv2")

[Abstract, Provider("MyProvider") : ToSubClass]
class MyClass_BaseDisk
{
  [read : ToSubClass, key : ToSubClass ] string DeviceID;
  [read : ToSubClass] uint32 State;
  [read : ToSubClass, write : ToSubClass] uint64 LimitUsers;
};

如需詳細資訊,請參閱 建立衍生類別 ,以取得衍生自這個基類之動態類別的範例。

使用 C++ 建立基類

使用 WMI API 建立基類主要是一系列的 Put 命令,這些命令會定義類別,並使用 WMI 註冊類別。 此 API 的主要用途是讓用戶端應用程式能夠建立基類。 不過,您也可以讓提供者使用此 API 來建立基類。 例如,如果您認為提供者的 MOF 程式碼不會正確安裝,您可以指示提供者在 WMI 存放庫中自動建立正確的類別。 如需提供者的詳細資訊,請參閱 撰寫類別提供者

注意

類別在執行提供者期間無法變更。 您必須停止活動、變更 類別,然後重新開機 Windows 管理服務。 目前無法偵測類別變更。

 

程式碼需要下列參考才能正確編譯。

#include <wbemidl.h>

您可以使用 WMI 的 COM API,以程式設計方式建立新的基類。

使用 WMI API 建立新的基類

  1. 藉由呼叫 IWbemServices::GetObject 方法,並將 strObjectPath 參數設定為 Null 值,以擷取新類別的定義。

    下列程式碼範例示範如何擷取新類別的定義。

    IWbemServices* pSvc = 0;
    IWbemContext* pCtx = 0;
    IWbemClassObject* pNewClass = 0;
    IWbemCallResult* pResult = 0;
    HRESULT hRes = pSvc->GetObject(0, 0, pCtx, &pNewClass, &pResult);
    
  2. 使用IWbemClassObject::P ut方法呼叫來設定__CLASS系統屬性,以建立 類別的名稱。

    下列程式碼範例示範如何藉由設定 __CLASS 系統屬性來命名 類別。

    VARIANT v;
    VariantInit(&v);
    V_VT(&v) = VT_BSTR;
    
    V_BSTR(&v) = SysAllocString(L"Example");
    BSTR Class = SysAllocString(L"__CLASS");
    pNewClass->Put(Class, 0, &v, 0);
    SysFreeString(Class);
    VariantClear(&v);
    
  3. 呼叫 IWbemClassObject::P ut來建立索引鍵屬性或屬性。

    下列程式碼範例說明如何建立 Index 屬性,其標示為步驟 4 中的索引鍵屬性。

      BSTR KeyProp = SysAllocString(L"Index");
      pNewClass->Put(KeyProp, 0, NULL, CIM_STRING);
    
  4. 先呼叫IWbemClassObject::GetPropertyQualifierSet方法,然後再呼叫IWbemQualifierSet::P ut方法,將Key標準限定詞附加至 key 屬性。

    下列程式碼範例示範如何將 Key 標準限定詞附加至 key 屬性。

      IWbemQualifierSet *pQual = 0;
      pNewClass->GetPropertyQualifierSet(KeyProp, &pQual);
      SysFreeString(KeyProp);
    
      V_VT(&v) = VT_BOOL;
      V_BOOL(&v) = VARIANT_TRUE;
      BSTR Key = SysAllocString(L"Key");
    
      pQual->Put(Key, &v, 0);   // Flavors not required for Key 
      SysFreeString(Key);
    
      // No longer need the qualifier set for "Index"
      pQual->Release();   
      VariantClear(&v);
    
  5. 使用 IWbemClassObject::P ut建立 類別的其他屬性。

    下列程式碼範例說明如何建立其他屬性。

      V_VT(&v) = VT_BSTR;
      V_BSTR(&v) = SysAllocString(L"<default>");
      BSTR OtherProp = SysAllocString(L"OtherInfo");
      pNewClass->Put(OtherProp, 0, &v, CIM_STRING);
      SysFreeString(OtherProp);
      VariantClear(&v);
    
      OtherProp = SysAllocString(L"IntVal");
      pNewClass->Put(OtherProp, 0, NULL, CIM_SINT32); // NULL is default
      SysFreeString(OtherProp);
    
  6. 呼叫 IWbemServices::P utClass來註冊新的類別。

    因為您無法在註冊新類別之後定義索引鍵和索引,所以在呼叫 PutClass之前,請確定您已定義所有屬性。

    下列程式碼範例說明如何註冊新的類別。

      hRes = pSvc->PutClass(pNewClass, 0, pCtx, &pResult);
      pNewClass->Release();
    

下列程式碼範例結合了上一個程式中討論的程式碼範例,並示範如何使用 WMI API 建立基類。

void CreateClass(IWbemServices *pSvc)
{
  IWbemClassObject *pNewClass = 0;
  IWbemContext *pCtx = 0;
  IWbemCallResult *pResult = 0;

  // Get a class definition. 
  // ============================
  HRESULT hRes = pSvc->GetObject(0, 0, pCtx, &pNewClass, &pResult);
  VARIANT v;
  VariantInit(&v);

  // Create the class name.
  // ============================
  V_VT(&v) = VT_BSTR;
  V_BSTR(&v) = SysAllocString(L"Example");
  BSTR Class = SysAllocString(L"__CLASS");
  pNewClass->Put(Class, 0, &v, 0);
  SysFreeString(Class);
  VariantClear(&v);

  // Create the key property. 
  // ============================
  BSTR KeyProp = SysAllocString(L"Index");
  pNewClass->Put(KeyProp, 0, NULL, CIM_STRING);

  // Attach Key qualifier to mark the "Index" property as the key.
  // ============================
  IWbemQualifierSet *pQual = 0;
  pNewClass->GetPropertyQualifierSet(KeyProp, &pQual);
  SysFreeString(KeyProp);

  V_VT(&v) = VT_BOOL;
  V_BOOL(&v) = VARIANT_TRUE;
  BSTR Key = SysAllocString(L"Key");

  pQual->Put(Key, &v, 0);   // Flavors not required for Key 
  SysFreeString(Key);

  // No longer need the qualifier set for "Index"
  pQual->Release();     
  VariantClear(&v);

  // Create other properties.
  // ============================
  V_VT(&v) = VT_BSTR;
  V_BSTR(&v) = SysAllocString(L"<default>");
  BSTR OtherProp = SysAllocString(L"OtherInfo");
  pNewClass->Put(OtherProp, 0, &v, CIM_STRING);
  SysFreeString(OtherProp);
  VariantClear(&v);

  OtherProp = SysAllocString(L"IntVal");
  pNewClass->Put(OtherProp, 0, NULL, CIM_SINT32); // NULL is default
  SysFreeString(OtherProp);
  
  // Register the class with WMI
  // ============================
  hRes = pSvc->PutClass(pNewClass, 0, pCtx, &pResult);
  pNewClass->Release();
}

建立類別