共用方式為


呼叫提供者方法

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

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

使用腳本呼叫提供者方法

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

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

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

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

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

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

  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::Put 方法,設定輸入參數類別的屬性。
    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;
}

呼叫方法