다음을 통해 공유


공급자 메서드 호출

공급자 메서드는 WMI(Windows Management Instrumentation) 공급자에 의해 구현되는 메서드입니다. 이 메서드는 소프트웨어 또는 하드웨어의 데이터를 나타내기 위해 공급자가 정의한 클래스에서 찾을 수 있습니다. 예를 들어 Win32_Service 클래스에는 서비스를 시작, 중지, 다시 시작, 일시 중지 및 변경하는 메서드가 있습니다.

공급자 메서드는 다음 형식의 메서드와 혼동해서는 안 됩니다.

스크립팅을 사용하여 공급자 메서드 호출

VBScript, PowerShell 또는 Perl과 같은 모든 자동화 언어는 WMI 메서드를 호출할 수 있습니다. 일부 언어는 직접 액세스사용할 수 있지만 다른 언어는 SWbemServices.ExecMethod 사용하여 공급자 메서드를 간접적으로 실행해야 합니다.

다음 절차에서는 Scripting API를 사용하고 직접 액세스를 사용하여 공급자 메서드를 호출하는 방법을 설명합니다.

Scripting API 및 직접 액세스를 사용하여 공급자 메서드를 호출하려면

  1. VBScript 또는 PowerShell에 이 방법을 사용합니다.

  2. 실행하려는 메서드가 구현되었는지 확인합니다.

    일부 클래스에는 공급자가 지원하지 않는 메서드가 정의되어 있습니다. 메서드가 구현되지 않은 경우 실행할 수 없습니다. 메서드에 Implemented 한정자를 포함하는지 확인하여 메서드가 구현되는지 확인할 수 있습니다. 자세한 내용은 WMI 한정자WMI 한정자 액세스를 참조하세요. WMI가 설치된 운영 체제에서 사용할 수 있는 지원되지 않는 Wbemtest.exe 유틸리티를 실행하여 공급자 클래스 메서드에 Implemented 한정자가 설정되어 있는지 확인할 수도 있습니다.

  3. 실행하려는 메서드가정적 메서드인지 아니면 비정적 메서드인지 확인합니다.

    정적 메서드는 WMI 클래스에만 적용되며 클래스의 특정 인스턴스에는 적용되지 않습니다. 예를 들어 Win32_Process 클래스의 Create 메서드는 이 클래스의 인스턴스 없이 새 프로세스를 만드는 데 사용하기 때문에 정적 메서드입니다. 비정적 메서드는 클래스의 인스턴스에만 적용됩니다. 예를 들어 Win32_Process 클래스의 Terminate 메서드는 해당 프로세스의 인스턴스가 있는 경우에만 프로세스를 종료하는 것이 합리적이기 때문에 비정적 메서드입니다. 정적 한정자는 메서드와 연결되어 있는지 확인하여 메서드가 정적인지 확인할 수 있습니다.

  4. 실행하려는 메서드가 포함된 클래스 또는 인스턴스를 검색합니다.

    자세한 내용은 WMI 클래스 또는 인스턴스 데이터를 검색하는 방법을참조하십시오.

  5. 메서드에 필요할 수 있는 모든 보안 설정을 설정합니다.

    메서드의 Privileges 한정자의 값을 검사하여 메서드에 필요한 권한을 확인할 수 있습니다. 예를 들어 Win32_OperatingSystem 클래스 Shutdown 메서드를 사용하려면 "SeShutdownPrivilege" 권한을 설정해야 합니다. 자세한 내용은 권한 있는 작업 실행참조하세요.

  6. 메서드를 호출하고 반환 값을 검사하여 메서드가 성공했는지 확인합니다.

다음 코드 예제에서는 메모장 프로세스를 만들고 직접 액세스를 사용하여 프로세스 ID를 가져옵니다.

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer _
    & "\root\cimv2:Win32_Process")

Error = objWMIService.Create("notepad.exe", null, _
    null, intProcessID)
If Error = 0 Then
    Wscript.Echo "Notepad was started with a process ID of " _
       & intProcessID & "."
Else
    Wscript.Echo "Notepad could not be started due to error " _
       & Error & "."
End If  

try
{ 
    $myProcess = ([wmiclass]"win32_process").create("notepad.exe", $null, $null) 
}
catch 
{
    "Notepad could not be started due to the following error:"
    $error[0]
    return 
}
#else
"Notepad was started with a process ID of " + $myProcess.ProcessID

다음 절차에서는 Scripting API 및 SWbemServices.ExecMethod사용하여 공급자 메서드를 호출하는 방법을 설명합니다.

Scripting API 및 SWbemServices.ExecMethod 사용하여 공급자 메서드를 호출하려면

  1. WMI 클래스 정의를 검색하여 정적 메서드를 실행합니다. 비정적 메서드를 실행하려면 WMI 클래스 인스턴스를 검색합니다.
  2. SWbemObjectSet.Item 메서드를 사용하여 클래스 또는 인스턴스의 SWbemObject.Methods_ 컬렉션에서 실행할 메서드를 검색합니다.
  3. 메서드에 대한 InParameters 개체를 가져오고 InParameters 개체생성에 설명된 대로 매개 변수를 설정합니다.
  4. SWbemServices.ExecMethod 메서드를 호출하여 반환 값을 SWbemObject 개체에 할당하여 출력 매개 변수를 저장합니다.
  5. 출력 매개 변수 개체의 값을 확인하여 메서드가 올바르게 실행되었는지 확인합니다.

다음 VBScript 코드 예제에서는 SWBemServices.ExecMethod호출하여 간접 접근 방식을 통해 이전 스크립트와 동일한 작업을 수행합니다.

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer _
    & "\root\cimv2")

Set objProcess = objWMIService.Get("Win32_Process")

' Obtain an InParameters object specific to 
'   the Win32_Process.Create method.
Set objInParam = _
    objProcess.Methods_("Create").inParameters.SpawnInstance_()

' Add the input parameters. 
objInParam.Properties_.item("CommandLine") = "Notepad"
objInParam.Properties_.item("CurrentDirectory") = NULL
objInParam.Properties_.item("ProcessStartupInformation") = NULL


Set objOutParams = objProcess.ExecMethod_("Create", objInParam) 
If Error = 0 Then
    Wscript.Echo "Notepad was started with a process ID of " _
       & objOutParams.ProcessId 
Else
    Wscript.Echo "Notepad could not be started due to error " & _
       objOutParams.ReturnValue
End If

다음 절차에서는 C++를 사용하여 공급자 메서드를 호출하는 방법을 설명합니다.

C++ 사용하여 공급자 메서드를 호출하려면

  1. WMI에 연결합니다.

    WMI에서 메서드를 호출하려면 먼저 WMI 네임스페이스에 대한 작업 연결이 있어야 합니다. 자세한 내용은 C++ 사용하여 WMI 애플리케이션 만들기 및 WMI 애플리케이션 대한 COM 초기화참조하세요.

    다음 예제에서는 WMI에 연결하는 방법을 보여줍니다. WMI 공급자 호출의 보안 문제에 대한 자세한 내용은 WMI 보안유지 관리를 참조하세요.

    HRESULT hr = CoInitialize(0);
        hr  =  CoInitializeSecurity(
                NULL, 
                -1, 
                NULL, 
                NULL,
                RPC_C_AUTHN_LEVEL_DEFAULT, 
                RPC_C_IMP_LEVEL_IMPERSONATE, 
                NULL, 
                EOAC_NONE, 
                NULL); 
        hr = CoCreateInstance(CLSID_WbemLocator, 0, 
                CLSCTX_INPROC_SERVER,
                IID_IWbemLocator, (LPVOID *) &pLocator);
        hr = pLocator->ConnectServer(path, NULL, NULL, 
                NULL, 0, NULL, NULL, &pNamespace);
  1. IWbemServices::GetObject 호출하여 호출하려는 메서드 클래스의 정의를 검색합니다.

    GetObject 메서드는 클래스 정의를 가리키는 IWbemClassObject 포인터를 반환합니다.

    hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL);
  1. 입력 매개 변수가 필요한 메서드의 경우 IWbemClassObject::GetMethod 메서드를 호출하여 입력 매개 변수 클래스 개체를 가져옵니다.

    GetMethod 입력 매개 변수 클래스를 가리키는 IWbemClassObject 포인터를 반환합니다.

    hr = pClass->GetMethod(MethodName, 0, &pInClass, NULL);
  1. IWbemClassObject::SpawnInstance 메서드를 호출하여 입력 매개 변수 클래스의 인스턴스를 생성합니다.
    hr = pInClass->SpawnInstance(0, &pInInst);
  1. IWbemClassObject::P ut 메서드를 호출하여 입력 매개 변수 클래스의 속성을 설정합니다.
    VARIANT var;
    var.vt = VT_BSTR;
    var.bstrVal= SysAllocString(L"hello");
    hr = pInInst->Put(ArgName, 0, &var, 0);
    VariantClear(&var);
  1. IWbemServices::ExecMethod 또는 IWbemServices::ExecMethodAsync호출하여 메서드를 호출합니다.

    ExecMethod경우 WMI는 호출의 출력 매개 변수를 반환합니다. ExecMethodAsync경우 WMI는 IWbemObjectSink호출을 통해 출력 매개 변수를 반환합니다. 자세한 내용은 메서드호출을 참조하세요.

    hr = pNamespace->ExecMethod(ClassPath, MethodName, 0, NULL, pInInst, &pOutInst, NULL);

다음 코드는 공급자 메서드를 호출하는 전체 예제입니다.

#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")

int main(int iArgCnt, char ** argv)
{
    IWbemLocator *pLocator = NULL;
    IWbemServices *pNamespace = 0;
    IWbemClassObject * pClass = NULL;
    IWbemClassObject * pOutInst = NULL;
    IWbemClassObject * pInClass = NULL;
    IWbemClassObject * pInInst = NULL;
  
    BSTR path = SysAllocString(L"root\\default");
    BSTR ClassPath = SysAllocString(L"TestMeth");
    BSTR MethodName = SysAllocString(L"Echo");
    BSTR ArgName = SysAllocString(L"sInArg");
    BSTR Text;

    // Initialize COM and connect to WMI.

    HRESULT hr = CoInitialize(0);
    hr  =  CoInitializeSecurity(NULL, -1, NULL, NULL,RPC_C_AUTHN_LEVEL_DEFAULT, 
                                RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); 
    hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
                          IID_IWbemLocator, (LPVOID *) &pLocator);
    hr = pLocator->ConnectServer(path, NULL, NULL, NULL, 0, NULL, NULL, &pNamespace);

    // Get the class object for the method definition.

    hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL);

    // Get the input-argument class object and 
    // create an instance.

    hr = pClass->GetMethod(MethodName, 0, &pInClass, NULL); 
    hr = pInClass->SpawnInstance(0, &pInInst);

    // Set the property.

    VARIANT var;
    var.vt = VT_BSTR;
    var.bstrVal= SysAllocString(L"hello");
    hr = pInInst->Put(ArgName, 0, &var, 0);
    VariantClear(&var);

    // Call the method.

    hr = pNamespace->ExecMethod(ClassPath, MethodName, 0, NULL, pInInst, &pOutInst, NULL);
    
    // Display the results. Note that the return 
    // value is in the property "ReturnValue"
    // and the returned string is in the 
    // property "sOutArg".

    hr = pOutInst->GetObjectText(0, &Text);
    printf("\nThe object text is:\n%S", Text);

    // Free up resources.

    SysFreeString(path);
    SysFreeString(ClassPath);
    SysFreeString(MethodName);
    SysFreeString(ArgName);
    SysFreeString(Text);
    pClass->Release();
    pInInst->Release();
    pInClass->Release();
    pOutInst->Release();
    pLocator->Release();
    pNamespace->Release();
    CoUninitialize();
    printf("Terminating normally\n");
    return 0;
}

메서드 호출