呼叫提供者方法

提供者方法是由 Windows Management Instrumentation (WMI) 提供者實作的方法。 方法位於提供者所定義的類別中,以代表軟體或硬體的資料。 例如, Win32_Service 類別有方法來啟動、停止、繼續、暫停和變更服務。

提供者方法不應該與下列類型的方法混淆:

使用腳本呼叫提供者方法

任何自動化語言,例如 VBScript、PowerShell 或 Perl,都可以呼叫 WMI 方法。 有些語言可以使用 直接存取,但有些語言必須使用 SWbemServices.ExecMethod 間接執行提供者方法。

下列程式描述如何使用腳本 API 和使用直接存取來呼叫提供者方法。

使用腳本 API 和直接存取呼叫提供者方法

  1. 針對 VBScript 或 PowerShell 使用此方法。

  2. 判斷您要執行的方法是否已實作。

    某些類別具有提供者不支援的方法。 如果未實作方法,您就無法執行此方法。 您可以藉由檢查方法是否有 作限定詞來判斷是否實作方法。 如需詳細資訊,請參閱 WMI 限定詞存取 WMI 限定詞。 您也可以藉由執行不支援的 Wbemtest.exe 公用程式,來判斷提供者類別方法是否已設定 作限定詞,可在已安裝 WMI 的任何作業系統上使用。

  3. 判斷您要執行的方法是否為 靜態方法 或非靜態方法。

    靜態方法僅適用于 WMI 類別,不適用於類別的特定實例。 例如,Win32_Process類別的Create方法是靜態方法,因為它可用來建立新的進程,而不需要這個類別的實例。 非靜態方法只適用于類別的實例。 例如,Win32_Process類別的Terminate方法是非靜態方法,因為如果該進程的實例存在,則唯一可以終止進程。 您可以藉由檢查靜態限定詞是否與 方法相關聯,來判斷方法是否為 靜態

  4. 擷取包含您要執行之方法的類別或實例。

    如需詳細資訊,請參閱 擷取 WMI 類別或實例資料

  5. 設定方法可能需要的任何安全性設定。

    您可以檢查 方法的 Privileges 限定詞中的值,來判斷方法所需的許可權。 例如, Win32_OperatingSystem 類別 Shutdown 方法會要求您設定 「SeShutdownPrivilege」 許可權。 如需詳細資訊,請參閱 執行特殊許可權作業

  6. 呼叫 方法並檢查傳回值,以判斷方法是否成功。

下列程式碼範例會建立記事本程式,並使用直接存取取得進程識別碼。

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

下列程式描述如何使用腳本 API 和 SWbemServices.ExecMethod呼叫提供者方法。

使用腳本 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::ExecMethodIWbemServices::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;
}

呼叫方法