次の方法で共有


WMI 基底クラスの作成

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

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

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

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

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

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

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

  • クラス名の最初は文字にする。

  • 先頭または末尾のアンダースコアは使用しない。

  • 残りのすべての字を文字、数字、またはアンダースコアにして定義する。

  • 一貫した名前付け規則を使用する。

    必須ではありませんが、クラスの名前付け規則としては、2 つの構成要素をアンダースコアでつないだものがよいでしょう。 可能であれば、ベンダー名で名前の前半を構成し、説明的なクラス名を後半部分にしましょう。

Note

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

 

MOF で、作成する基底クラスに class キーワードで名前を付けますが、親クラスを示すのではありません。

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

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

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

    class MyClass_BaseDisk
    {
    };
    

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

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

    次のコード例では、クラスを抽象として定義し、データを提供するプロバイダーを定義します。 ToSubClass 修飾子の flavor は、Provider 修飾子の情報が派生クラスによって継承されることを示します。

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

Note

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

 

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

#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 を呼び出して、キー プロパティを作成します。

    次のコード例は Index プロパティを作成する方法について記述しており、手順 4 でキー プロパティのラベルが付いています。

      BSTR KeyProp = SysAllocString(L"Index");
      pNewClass->Put(KeyProp, 0, NULL, CIM_STRING);
    
  4. Key 標準修飾子をキー プロパティにアタッチするには、最初に IWbemClassObject::GetPropertyQualifierSet メソッドを呼び出し、次に IWbemQualifierSet::Put メソッドを呼び出します。

    次のコード例は、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();
}

クラスの作成