Aufrufen einer Anbietermethode

Eine Anbietermethode ist eine Methode, die von einem Windows-Verwaltungsinstrumentation-(WMI-)Anbieter implementiert wird. Die Methode befindet sich in einer Klasse, die von einem Anbieter definiert wird, um Software- oder Hardwaredaten darzustellen. Beispielsweise verfügt die Klasse Win32_Service über Methoden zum Starten, Beenden, Fortsetzen, Anhalten und Ändern von Diensten.

Anbietermethoden sind nicht mit den folgenden Methodentypen zu verwechseln:

Aufrufen einer Anbietermethode mithilfe von Skripts

Mit jeder Automatisierungssprache, wie z. B. VBScript, PowerShell oder Perl, kann eine WMI-Methode aufgerufen werden. Einige Sprachen können direkten Zugriff verwenden, während andere SWbemServices.ExecMethod verwenden müssen, um die Anbietermethode indirekt auszuführen.

Im folgenden Verfahren wird beschrieben, wie Sie eine Anbietermethode mithilfe der Skript-API und des direkten Zugriffs aufrufen.

So rufen Sie eine Anbietermethode mithilfe der Skript-API und des direkten Zugriffs auf

  1. Verwenden Sie diesen Ansatz für VBScript oder PowerShell.

  2. Ermitteln Sie, ob die Methode implementiert ist, die Sie ausführen möchten.

    Einige Klassen verfügen über definierte Methoden, die von einem Anbieter nicht unterstützt werden. Wenn eine Methode nicht implementiert ist, können Sie sie nicht ausführen. Sie können ermitteln, ob eine Methode implementiert ist, indem Sie überprüfen, ob die Methode über den Qualifizierer Implementiert verfügt. Weitere Informationen finden Sie unter WMI-Qualifizierer und Zugreifen auf einen WMI-Qualifizierer. Sie können auch ermitteln, ob für eine Anbieterklassenmethode der Qualifizierer Implementiert festgelegt ist, indem Sie das nicht unterstützte Wbemtest.exe-Hilfsprogramm ausführen, das unter jedem Betriebssystem mit installiertem WMI verfügbar ist.

  3. Ermitteln Sie, ob die Methode, die Sie ausführen möchten, eine statische Methode oder eine nichtstatische Methode ist.

    Statische Methoden gelten nur für WMI-Klassen und nicht für bestimmte Instanzen einer Klasse. Beispielsweise ist die Create-Methode der Win32_Process-Klasse eine statische Methode, da sie zum Erstellen eines neuen Prozesses ohne Instanz dieser Klasse verwendet wird. Nichtstatische Methoden können nur auf Instanzen einer Klasse angewendet werden. Die Terminate-Methode der Win32_Process-Klasse ist beispielsweise eine nichtstatische Methode, da es nur sinnvoll ist, einen Prozess zu beenden, wenn eine Instanz dieses Prozesses vorhanden ist. Sie können feststellen, ob eine Methode statisch ist, indem Sie überprüfen, ob der Qualifizierer Statisch der -Methode zugeordnet ist.

  4. Rufen Sie die Klasse oder Instance ab, die die auszuführende Methode enthält.

    Weitere Informationen finden Sie unter Abrufen von WMI-Klassen- oder Instanzdaten.

  5. Richten Sie alle Sicherheitseinstellungen ein, die für die Methode möglicherweise erforderlich sind.

    Sie können häufig die Berechtigungen ermitteln, die eine Methode erfordert, indem Sie die Werte im Qualifizierer Berechtigungen der Methode untersuchen. Beispielsweise erfordert die Win32_OperatingSystemShutdown-Methode, dass Sie die Berechtigung „SeShutdownPrivilege“ festlegen. Weitere Informationen finden Sie unter Ausführen privilegierter Vorgänge.

  6. Rufen Sie die -Methode auf, und überprüfen Sie den Rückgabewert, um festzustellen, ob die Methode erfolgreich war.

Im folgenden Codebeispiel wird ein Editor-Prozess erstellt und die Prozess-ID mithilfe des direkten Zugriffs abgerufen.

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

Im folgenden Verfahren wird beschrieben, wie eine Anbietermethode mithilfe der Skript-API und der SWbemServices.ExecMethod aufgerufen wird.

So rufen Sie eine Anbietermethode mithilfe der Skript-API und SWbemServices.ExecMethod auf

  1. Rufen Sie die WMI-Klassendefinition ab, um eine statische Methode auszuführen. Rufen Sie die WMI-Klasseinstanz ab, um eine nichtstatische Methode auszuführen.
  2. Rufen Sie die auszuführende Methode aus der SWbemObject.Methods_-Sammlung Ihrer Klasse oder Instanz mithilfe der SWbemObjectSet.Item-Methode ab.
  3. Rufen Sie ein InParameters-Objekt für die Methode ab, und richten Sie die Parameter ein, wie unter Erstellen von InParameters-Objekten beschrieben.
  4. Rufen Sie die auszuführende SWbemServices.ExecMethod-Methode auf, und weisen Sie den Rückgabewert einem SWbemObject-Objekt zu, um die Ausgabeparameter zu speichern.
  5. Überprüfen Sie die Werte im Ausgabeparameterobjekt, um sicherzustellen, dass die Methode ordnungsgemäß ausgeführt wurde.

Im folgenden VBScript-Codebeispiel wird der gleiche Vorgang wie im vorherigen Skript durch den indirekten Ansatz durch Aufrufen von SWBemServices.ExecMethod ausgeführt.

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

Im folgenden Verfahren wird beschrieben, wie Sie eine Anbietermethode mit C++ aufrufen.

So rufen Sie eine Anbietermethode mit C++ auf

  1. Stellen Sie eine Verbindung mit WMI her.

    Um eine Methode in WMI aufzurufen, müssen Sie zunächst über eine funktionierende Verbindung mit einem WMI-Namespace verfügen. Weitere Informationen finden Sie unter Erstellen einer WMI-Anwendung mit C++ und Initialisieren von COM für eine WMI-Anwendung.

    Das folgende Beispiel zeigt, wie Sie eine Verbindung mit WMI herstellen. Weitere Informationen zu Sicherheitsproblemen in WMI-Anbieteraufrufen finden Sie unter Verwalten von WMI-Sicherheit.

    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. Rufen Sie IWbemServices::GetObject auf, um die Definition der Klasse der Methode abzurufen, die Sie aufrufen möchten.

    Die GetObject-Methode gibt einen IWbemClassObject-Zeiger zurück, der auf die Klassendefinition verweist.

    hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL);
  1. Rufen Sie für Methoden, die Eingabeparameter erfordern, die IWbemClassObject::GetMethod-Methode auf, um das Eingabeparameterklassenobjekt abzurufen.

    GetMethod gibt einen IWbemClassObject-Zeiger zurück, der auf die Eingabeparameterklasse verweist.

    hr = pClass->GetMethod(MethodName, 0, &pInClass, NULL);
  1. Generieren Sie eine Instanz der Eingabeparameterklasse mit einem Aufruf der IWbemClassObject::SpawnInstance-Methode.
    hr = pInClass->SpawnInstance(0, &pInInst);
  1. Legen Sie die Eigenschaften der Eingabeparameterklasse mit einem Aufruf der IWbemClassObject::P ut-Methode fest.
    VARIANT var;
    var.vt = VT_BSTR;
    var.bstrVal= SysAllocString(L"hello");
    hr = pInInst->Put(ArgName, 0, &var, 0);
    VariantClear(&var);
  1. Rufen Sie die Methode mit einem Aufruf von IWbemServices::ExecMethod oder IWbemServices::ExecMethodAsync auf.

    Bei ExecMethod gibt WMI alle Ausgabeparameter im Aufruf zurück. Bei ExecMethodAsync gibt WMI alle Ausgabeparameter über einen Aufruf von IWbemObjectSink zurück. Weitere Informationen finden Sie unter Aufrufen einer Methode.

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

Im folgenden Beispiel sehen Sie einen vollständigen Code für das Aufrufen einer Anbietermethode.

#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;
}

Aufrufen einer Methode