WMI 派生クラスの作成

WMI での派生クラスの作成は、基底クラスの作成とよく似ています。 基底クラスと同様に、最初に派生クラスを定義してから、その派生クラスを WMI に登録する必要があります。 主な違いは、最初に派生元の親クラスを見つける必要がある点です。 詳細については、「クラス プロバイダーの作成」と「インスタンス プロバイダーの作成」を参照してください。

プロバイダーに対してクラスを作成するおすすめの方法は、マネージド オブジェクト フォーマット (MOF) ファイルです。 相互に関連するいくつかの派生クラスは、それらがプロパティまたはメソッドの派生元とする基底クラスと共に、MOF ファイルにグループ化する必要があります。 各クラスを個別の MOF ファイルに配置する場合、プロバイダーを正常に動作させるには、その前に、各ファイルをコンパイルする必要があります。

クラスを作成した後、派生クラスで次のいずれかのアクティビティを実行する前に、クラスのすべてのインスタンスを削除する必要があります。

  • 派生クラスの親クラスを変更する。
  • プロパティを追加または削除する。
  • プロパティの種類を変更します。
  • キーまたはインデックス付き修飾子を追加または削除します。
  • SingletonDynamic、または Abstract 修飾子を追加または削除します。

注意

プロパティまたは修飾子を追加、削除、または変更するには、IWbemServices::PutClass または SWbemObject.Put_ を呼び出し、フラグ パラメータを "強制モード" に設定します。 Abstract 修飾子が使用できるのは、親クラスが抽象である場合のみです。

 

派生クラスを宣言するときは、次の規則と制限事項に従います。

  • 派生クラスの親クラスが既に存在している必要があります。

    親クラスの宣言は、派生クラスと同じ MOF ファイルまたは別のファイルに記述できます。 親クラスが不明な場合、コンパイラによって実行時エラーが生成されます。

  • 派生クラスは親クラスを 1 つだけ持つことができます。

    WMI では多重継承がサポーされていません。 ただし、親クラスは複数の派生クラスを持つことができます。

  • 派生クラスのインデックスは定義できますが、WMI ではこれらのインデックスは使用されません。

    したがって、派生クラスにインデックスを指定しても、派生クラスのインスタンスに対するクエリのパフォーマンスは向上しません。 派生クラスの親クラスにインデックス付きプロパティを指定すると、派生クラスに対するクエリのパフォーマンスを向上させることができます。

  • 派生クラス定義はさらに複雑にすることができ、エイリアス、修飾子、修飾子のフレーバーなどの機能を含めることができます。

    詳細については、エイリアスの作成に関する記事と、「修飾子の追加」を参照してください。

  • 修飾子を変更したり、基底クラス プロパティの既定値を変更したり、基底クラスの参照または埋め込みオブジェクト プロパティをより厳密に入力したりする場合は、基底クラス全体をもう一度宣言する必要があります。

  • WMI クラスで定義できるプロパティの最大数は 1024 です。

注意

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

 

基底クラスと同様に、この手法はクライアント アプリケーションで最も一般的に使用されます。 ただし、プロバイダーで派生クラスを作成することもできます。 詳細については、基底クラスの作成に関する記事と、「クラス プロバイダーの作成」を参照してください。

このトピックのコードの例を正しくコンパイルするには、次の #include ステートメントが必要です。

#include <wbemidl.h>

次の手順では、C++ を使用して派生クラスを作成する方法について説明します。

C++ を使用して派生クラスを作成するには

  1. IWbemServices::GetObject への呼び出しを使用して、基底クラスを見つけます。

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

    // The pSv variable is of type IWbemServices *
    
    IWbemClassObject *pNewDerivedClass = 0;
    IWbemClassObject *pExampleClass = 0;
    IWbemContext *pCtx = 0;
    IWbemCallResult *pResult = 0;
    
    BSTR PathToClass = SysAllocString(L"Example");
    HRESULT hRes = pSvc->GetObject(PathToClass, 0, pCtx, &pExampleClass, &pResult);
    SysFreeString(PathToClass);
    
  2. IWbemClassObject::SpawnDerivedClass への呼び出しを使用して、基底クラスから派生オブジェクトを作成します。

    次のコード例は、派生クラス オブジェクトを作成する方法を示しています。

    pExampleClass->SpawnDerivedClass(0, &pNewDerivedClass);
    pExampleClass->Release();  // Don't need the parent class any more
    
  3. IWbemClassObject::Put メソッドへの呼び出しで __CLASS システム プロパティを設定して、クラスの名前を設定します。

    次のコード例は、派生クラスに名前を割り当てる方法を示しています。

    VARIANT v;
    VariantInit(&v);
    
    V_VT(&v) = VT_BSTR;
    V_BSTR(&v) = SysAllocString(L"Example2");
    BSTR Class = SysAllocString(L"__CLASS");
    pNewDerivedClass->Put(Class, 0, &v, 0);
    SysFreeString(Class);
    VariantClear(&v);
    
  4. IWbemClassObject::Put を使用して、追加のプロパティを作成します。

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

    BSTR OtherProp = SysAllocString(L"OtherInfo2");
    pNewDerivedClass->Put(OtherProp, 0, NULL, CIM_STRING); 
    SysFreeString(OtherProp);
    
  5. IWbemServices::PutClass を呼び出して、新しいクラスを保存します。

    次のコード例は、新しい派生クラスを保存する方法を示しています。

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

次のコード例では、前の手順で説明したコード例を組み合わせて、WMI API を使用して派生クラスを作成する方法を説明しています。

void CreateDerivedClass(IWbemServices *pSvc)
{
  IWbemClassObject *pNewDerivedClass = 0;
  IWbemClassObject *pExampleClass = 0;
  IWbemContext *pCtx = 0;
  IWbemCallResult *pResult = 0;

  BSTR PathToClass = SysAllocString(L"Example");
  HRESULT hRes = pSvc->GetObject(PathToClass, 0, pCtx, 
    &pExampleClass, &pResult);
  SysFreeString(PathToClass);

  if (hRes != 0)
    return;

  pExampleClass->SpawnDerivedClass(0, &pNewDerivedClass);
  pExampleClass->Release();  // The parent class is no longer needed

  VARIANT v;
  VariantInit(&v);

  // Create the class name.
  // =====================

  V_VT(&v) = VT_BSTR;
  V_BSTR(&v) = SysAllocString(L"Example2");
  BSTR Class = SysAllocString(L"__CLASS");
  pNewDerivedClass->Put(Class, 0, &v, 0);
  SysFreeString(Class);
  VariantClear(&v);

  // Create another property.
  // =======================
  BSTR OtherProp = SysAllocString(L"OtherInfo2");
  // No default value
  pNewDerivedClass->Put(OtherProp, 0, NULL, CIM_STRING); 
  SysFreeString(OtherProp);
  
  // Register the class with WMI. 
  // ============================
  hRes = pSvc->PutClass(pNewDerivedClass, 0, pCtx, &pResult);
  pNewDerivedClass->Release();
}

次の手順では、MOF コードを使用して派生クラスを定義する方法について説明します。

MOF コードを使用して派生クラスを定義するには

  1. Class キーワードの後に派生クラスの名前と、コロンで区切られた親クラスの名前を指定して、派生クラスを定義します。

    次のコード例では、派生クラスの実装を示しています。

    class MyClass 
    {
        [key] string   strProp;
        sint32   dwProp1;
        uint32       dwProp2;
    };
    
    class MyDerivedClass : MyClass
    {
        string   strDerivedProp;
        sint32   dwDerivedProp;
    };
    
  2. 完了したら、MOF コンパイラを使用して MOF コードをコンパイルします。

    詳細については、「MOF ファイルのコンパイル」を参照してください。

クラスの作成