Udostępnij za pośrednictwem


Wywoływanie metody dostawcy

Metoda dostawcy to metoda implementowana przez dostawcę instrumentacji zarządzania Windows (WMI). Metoda znajduje się w klasie zdefiniowanej przez dostawcę do reprezentowania danych z oprogramowania lub sprzętu. Na przykład klasa Win32_Service ma metody uruchamiania, zatrzymywania, wznawiania, wstrzymywania i zmieniania usług.

Metody dostawcy nie powinny być mylone z następującymi typami metod:

Wywoływanie metody dostawcy przy użyciu skryptów

Dowolny język automatyzacji, taki jak VBScript, PowerShell lub Perl, może wywołać metodę WMI. Niektóre języki mogą używać bezpośredniego dostępu, jednak inne muszą korzystać z SWbemServices.ExecMethod, aby pośrednio wykonywać metodę dostawcy.

Poniższa procedura opisuje sposób wywoływania metody dostawcy przy użyciu interfejsu API obsługi skryptów i bezpośredniego dostępu.

Aby wywołać metodę dostawcy przy użyciu interfejsu API obsługi skryptów i dostępu bezpośredniego

  1. Użyj tego podejścia dla języka VBScript lub programu PowerShell.

  2. Ustal, czy metoda, którą chcesz wykonać, jest implementowana.

    Niektóre klasy mają zdefiniowane metody, które nie są obsługiwane przez dostawcę. Jeśli metoda nie jest zaimplementowana, nie można jej wykonać. Można określić, czy metoda jest implementowana, sprawdzając, czy metoda ma kwalifikator zaimplementowany. Aby uzyskać więcej informacji, zobacz kwalifikatory WMI i Uzyskiwanie kwalifikatora WMI. Można również określić, czy metoda klasy dostawcy ma ustawiony kwalifikator Zaimplementowane, poprzez uruchomienie nieobsługiwanego narzędzia Wbemtest.exe dostępnego w dowolnym systemie operacyjnym z zainstalowaną usługą WMI.

  3. Ustal, czy metoda, którą chcesz wykonać, jest metodą statyczną lub metodą niestatyczną.

    Metody statyczne mają zastosowanie tylko do klas WMI, a nie do określonych wystąpień klasy. Na przykład metoda Create klasy Win32_Process jest metodą statyczną, ponieważ użyj jej do utworzenia nowego procesu bez wystąpienia tej klasy. Metody niestatyczne dotyczą tylko wystąpień klasy. Na przykład metoda Terminate klasy Win32_Process jest metodą niestatyczną, ponieważ warto zakończyć proces tylko wtedy, gdy istnieje wystąpienie tego procesu. Możesz określić, czy metoda jest statyczna, sprawdzając, czy Static kwalifikator jest skojarzony z metodą.

  4. Pobierz klasę lub wystąpienie zawierające metodę, którą chcesz wykonać.

    Aby uzyskać więcej informacji, zobacz Znajdowanie klasy WMI lub danych wystąpienia.

  5. Skonfiguruj ustawienia zabezpieczeń, których może wymagać metoda.

    Często można określić uprawnienia wymagane przez metodę, sprawdzając wartości w Uprawnienia kwalifikatorze metody. Na przykład metoda klasy Win32_OperatingSystemShutdown wymaga ustawienia uprawnień "SeShutdownPrivilege". Aby uzyskać więcej informacji, zobacz Wykonywanie operacji uprzywilejowanych.

  6. Wywołaj metodę i sprawdź wartość zwracaną, aby określić, czy metoda zakończyła się pomyślnie.

Poniższy przykład kodu tworzy proces programu Notatnik i pobiera identyfikator procesu przez bezpośredni dostęp.

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

Poniższa procedura opisuje sposób wywoływania metody dostawcy przy użyciu API skryptowego i SWbemServices.ExecMethod.

Aby wywołać metodę providera przy użyciu API skryptów i SWbemServices.ExecMethod

  1. Pobierz definicję klasy WMI, aby wykonać metodę statyczną. Pobierz wystąpienie klasy WMI, aby wykonać metodę niestatyczną.
  2. Pobierz metodę do uruchomienia z kolekcji SWbemObject.Methods_ klasy lub instancji przy użyciu metody SWbemObjectSet.Item.
  3. Uzyskaj dla metody obiekt InParameters i skonfiguruj parametry zgodnie z opisem w Constructing InParameters Objects.
  4. Wywołaj metodę SWbemServices.ExecMethod, aby wykonać i przypisać wartość zwracaną do obiektu SWbemObject w celu przechowywania parametrów wyjściowych.
  5. Sprawdź wartości w obiekcie parametrów wyjściowych, aby sprawdzić, czy metoda została wykonana poprawnie.

Poniższy przykład kodu VBScript wykonuje tę samą operację co poprzedni skrypt przez podejście pośrednie przez wywołanie 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

Poniższa procedura opisuje sposób wywoływania metody dostawcy przy użyciu języka C++.

Aby wywołać metodę dostawcy przy użyciu języka C++

  1. Połącz się z WMI.

    Aby wywołać metodę w usłudze WMI, najpierw musisz mieć działające połączenie z przestrzenią nazw usługi WMI. Aby uzyskać więcej informacji, zobacz Tworzenie aplikacji WMI przy użyciu C++ oraz Inicjowanie COM dla aplikacji WMI.

    W poniższym przykładzie pokazano, jak nawiązać połączenie z usługą WMI. Aby uzyskać więcej informacji na temat problemów z zabezpieczeniami podczas wywołań usługodawcy WMI, zobacz Obsługa zabezpieczeń usługi 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. Wywołaj metodę IWbemServices::GetObject, aby pobrać definicję klasy metody, którą chcesz wywołać.

    Metoda GetObject zwraca wskaźnik IWbemClassObject wskazujący definicję klasy.

    hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL);
  1. W przypadku metod, które wymagają parametrów wejściowych, wywołaj metodę IWbemClassObject::GetMethod, aby uzyskać obiekt klasy parametrów wejściowych.

    getMethod zwraca wskaźnik IWbemClassObject wskazujący klasę parametrów wejściowych.

    hr = pClass->GetMethod(MethodName, 0, &pInClass, NULL);
  1. Wygeneruj wystąpienie klasy parametrów wejściowych za pomocą wywołania metody IWbemClassObject::SpawnInstance.
    hr = pInClass->SpawnInstance(0, &pInInst);
  1. Ustaw właściwości klasy parametrów wejściowych za pomocą wywołania metody IWbemClassObject::Put.
    VARIANT var;
    var.vt = VT_BSTR;
    var.bstrVal= SysAllocString(L"hello");
    hr = pInInst->Put(ArgName, 0, &var, 0);
    VariantClear(&var);
  1. Wywołaj metodę za pomocą wywołania metody IWbemServices::ExecMethod lub IWbemServices::ExecMethodAsync.

    W przypadku ExecMethod, WMI zwraca dowolne parametry wyjściowe przy wywołaniu. W przypadku ExecMethodAsyncWMI zwraca wszystkie parametry wyjściowe za pomocą wywołania metody IWbemObjectSink. Aby uzyskać więcej informacji, zobacz Wywoływanie metody.

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

Poniższy kod jest kompletnym przykładem wywoływania metody dostawcy.

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

Wywoływanie metody