WMI 基底クラスの作成

WMI プロバイダーの新しい WMI 基底クラスを作成するのに推奨されている方法は、マネージド オブジェクト フォーマット (MOF) ファイルです。 WMI 用 COM API を使用して基底クラスを作成することもできます。 スクリプトで基底クラスまたは派生クラスを作成できますが、プロバイダーがクラスとそのサブクラスにデータを提供しなければ、そのクラスは役に立ちません。

このトピックでは次のセクションを扱います。

MOF を使用した基底クラスの作成

通常、WMI クラスは継承に依存します。 基底クラスを作成する前に、Distributed Management Task Force (DMTF) から使用可能な Common Information Model (CIM) クラスを確認します。

多くの派生クラスで同じプロパティが使用される場合は、これらのプロパティとメソッドを基底クラスに配置します。 WMI クラスで定義できるプロパティの最大数は 1024 です。

基底クラスを作成するときは、クラス名に関する次のガイドライン一覧を確認してください。

  • 大文字と小文字の両方を使用する。

  • クラス名は文字で始めます。

  • 先頭または末尾にアンダースコアは使用しないでください。

  • その他の文字はすべて、文字、数字、またはアンダースコアで定義します。

  • 一貫性のある名前付け規則を使用する。

    必須ではありませんが、クラスの適切な名前付け規則は、2 つのコンポーネントをアンダースコアで結合することです。 可能であれば、ベンダー名を名前の前半に、説明的なクラス名を名前の後半に置いた構成にするほうがよいでしょう。

Note

プロバイダーの実行中にクラスを変更することはできません。 アクティビティを停止し、クラスを変更してから、Windows Management サービスを再起動する必要があります。 現在、クラスの変更を検出することはできません。

 

MOF では、基底クラスを作成するのに、親クラスを示すのではなく、class キーワードを使用して名前を付けます。

MOF コードを使用して基底クラスを作成するには

  1. class キーワードを新しいクラスの名前と共に使用し、その後に中かっこのペアとセミコロンを続けます。 中かっこの間にクラスのプロパティとメソッドを追加します。 コード例を次に示します。

    次のコード例は、基底クラスを定義する方法を示しています。

    class MyClass_BaseDisk
    {
    };
    

    次のコード例は、基底クラスの定義が正しくないことを示しています。

    class MyClass_BaseDisk : CIM_LogicalDisk
    {
    };
    
  2. class キーワードの前に任意のクラス修飾子を追加して、クラスの使用方法を変更します。 角かっこの間に修飾子を配置します。 クラスを変更するための修飾子の詳細については、「WMI 修飾子」を参照してください。 このクラスのインスタンスを直接作成できないことを示すには、Abstract 修飾子を使用します。 抽象クラスは、多くの場合、複数の派生クラスで使用されるプロパティまたはメソッドを定義するために使用されます。 詳細については、「派生クラスの作成」を参照してください。

    次のコード例では、クラスを抽象として定義し、データを提供するプロバイダーを定義します。 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.exe newmof.mof

    -N スイッチ、またはプリプロセッサ コマンド #pragma namespace を使用して名前空間を指定しない場合、コンパイル済みの MOF クラスはリポジトリの root\default namespace に格納されます。 詳しくは、mofcomp を参照してください。

次のコード例では、前の手順で説明した MOF コード例を組み合わせ、MOF を使用して root\cimv2 namespace に基底クラスを作成する方法を示します。

#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 を使用した基底クラスの作成は、クラスを定義し、WMI にクラスを登録する一連の Put コマンドが主になります。 この API の主な目的は、クライアント アプリケーションで基底クラスを作成できるようにすることです。 ただし、プロバイダーにこの API を使用して基底クラスを作成してもらうこともできます。 たとえば、プロバイダーの MOF コードが正しくインストールされないと思われる場合は、WMI リポジトリに正しいクラスを自動的に作成するようにプロバイダーに指示できます。 プロバイダーの詳細については、「クラス プロバイダーの作成」を参照してください。

Note

プロバイダーの実行中にクラスを変更することはできません。 アクティビティを停止し、クラスを変更してから、Windows Management サービスを再起動する必要があります。 現在、クラスの変更を検出することはできません。

 

コードを正しくコンパイルするには、次の参照が必要です。

#include <wbemidl.h>

WMI 用 COM API を使用して、新しい基底クラスをプログラムで作成できます。

WMI API を使用して新しい基底クラスを作成するには

  1. strObjectPath パラメーターを null 値に設定したうえで、IWbemServices::GetObject メソッドを呼び出して、新しいクラスの定義を取得します。

    次のコード例では、新しいクラスの定義を取得する方法を示します。

    IWbemServices* pSvc = 0;
    IWbemContext* pCtx = 0;
    IWbemClassObject* pNewClass = 0;
    IWbemCallResult* pResult = 0;
    HRESULT hRes = pSvc->GetObject(0, 0, pCtx, &pNewClass, &pResult);
    
  2. IWbemClassObject::Put メソッドを呼び出し、__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::Put を呼び出して、キーのプロパティを作成します。

    次のコード例では、手順 4 でキー プロパティとしてラベル付けされた Index プロパティを作成する方法について説明します。

      BSTR KeyProp = SysAllocString(L"Index");
      pNewClass->Put(KeyProp, 0, NULL, CIM_STRING);
    
  4. 最初に IWbemClassObject::GetPropertyQualifierSet メソッドを呼び出し、次に IWbemQualifierSet::Put メソッドを呼び出して、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::Put を使用して、クラスの他のプロパティを作成します。

    次のコード例では、追加のプロパティを作成する方法について説明します。

      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::PutClass を呼び出して、新しいクラスを登録します。

    新しいクラスを登録した後はキーとインデックスを定義できないため、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();
}

クラスの作成