WMI 기본 클래스 만들기

WMI 공급자를 위한 새 WMI 기본 클래스를 만드는 데 권장하는 방법은 MOF(Managed Object Format) 파일입니다. WMI용 COM API를 사용하여 기본 클래스를 만들 수도 있습니다. 공급자가 클래스 및 관련 하위 클래스에 데이터를 제공하지 않고도 스크립트에서 기본 또는 파생 클래스를 만들 수 있지만, 이 클래스는 유용하지 않습니다.

이 항목에서 다루는 섹션은 다음과 같습니다.

MOF를 사용하여 기본 클래스 만들기

WMI 클래스는 일반적으로 상속에 의존합니다. 기본 클래스를 만들기 전에 DMTF(분산 관리 태스크 포스)에서 사용할 수 있는 CIM(공용 정보 모델) 클래스를 확인합니다.

많은 파생 클래스에서 동일한 속성을 사용한다면, 이러한 속성과 메서드를 기본 클래스에 배치합니다. WMI 클래스에서는 속성을 1024개까지 정의할 수 있습니다.

기본 클래스를 만들 때는 클래스 이름에 대한 다음 지침 목록을 확인하세요.

  • 대문자와 소문자를 모두 사용합니다.

  • 클래스 이름은 문자로 시작합니다.

  • 선행 또는 후행 밑줄을 사용하지 않습니다.

  • 나머지 모든 문자를 문자, 숫자 또는 밑줄로 정의합니다.

  • 일관된 명명 규칙을 사용합니다.

    필수는 아니지만, 두 구성 요소를 밑줄로 연결하는 것은 훌륭한 클래스 명명 방법입니다. 가능한 경우 공급업체 이름이 이름의 첫 번째 절반을 구성해야 하며, 내용을 설명하는 클래스 이름이 두 번째 절반이어야 합니다.

참고

공급자를 실행하는 동안에는 클래스를 변경할 수 없습니다. 작업을 중지하고 클래스를 변경한 다음 Windows Management 서비스를 다시 시작해야 합니다. 현재는 클래스 변경을 검색할 수 없습니다.

 

MOF에서 class 키워드를 사용하여 이름을 지정하되 부모 클래스를 나타내지는 않는 기본 클래스를 만듭니다.

MOF 코드를 사용하여 기본 클래스를 만드는 방법

  1. class 키워드를 새 클래스의 이름과 함께 사용하고, 중괄호 쌍과 세미콜론을 덧붙입니다. 중괄호 사이에 클래스의 속성과 메서드를 추가합니다. 다음 코드 예제가 제공됩니다.

    다음 코드 예제에서는 기본 클래스를 정의하는 방법을 확인할 수 있습니다.

    class MyClass_BaseDisk
    {
    };
    

    다음 코드 예제에서는 기본 클래스의 잘못된 정의를 확인할 수 있습니다.

    class MyClass_BaseDisk : CIM_LogicalDisk
    {
    };
    
  2. 클래스 키워드 앞에 아무 클래스 한정자를 추가하여 클래스 사용 방식을 수정합니다. 대괄호 사이에 한정자를 배치합니다. 클래스 수정용 한정자에 대한 자세한 내용은 WMI 한정자를 참조하세요. Abstract 한정자를 사용하여 사용자가 이 클래스의 인스턴스를 만들 수 없음을 나타냅니다. 추상 클래스는 주로 여러 파생 클래스에서 사용할 속성 또는 메서드를 정의하는 용도로 사용합니다. 자세한 내용은 파생 클래스 만들기를 참조하세요.

    다음 코드 예제에서는 클래스를 추상으로 정의하고 데이터를 제공할 공급자를 정의합니다. ToSubClass 한정자인 flavorProvider 한정자의 정보가 파생 클래스에서 상속함을 나타냅니다.

    [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 namespace를 사용하여 네임스페이스를 지정하지 않으면, 컴파일된 MOF 클래스는 리포지토리의 root\default 네임스페이스에 저장됩니다. 자세한 내용은 mofcomp를 참조하세요.

다음 코드 예제에서는 이전 절차에서 설명한 MOF 코드 예제를 결합하고 WMI API를 사용하여 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 리포지토리에 올바른 클래스를 자동으로 만들도록 지시할 수 있습니다. 공급자에 대한 자세한 내용은 클래스 공급자 작성을 참조하세요.

참고

공급자를 실행하는 동안에는 클래스를 변경할 수 없습니다. 작업을 중지하고 클래스를 변경한 다음 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();
}

클래스 만들기