Dela via


Anropa en leverantörsmetod

En providermetod är en metod som implementeras av en WMI-provider (Windows Management Instrumentation). Metoden finns i en klass som definierats av en provider för att representera data från programvara eller maskinvara. Klassen Win32_Service har till exempel metoder för att starta, stoppa, återuppta, pausa och ändra tjänster.

Providermetoder bör inte förväxlas med följande typer av metoder:

Anropa en providermetod med skript

Alla automationsspråk, till exempel VBScript, PowerShell eller Perl, kan anropa en WMI-metod. Vissa språk kan använda direktåtkomst, men andra måste använda SWbemServices.ExecMethod för att köra providermetoden indirekt.

Följande procedur beskriver hur du anropar en providermetod med hjälp av API för skript och direktåtkomst.

Anropa en providermetod med hjälp av API:et för skript och direktåtkomst

  1. Använd den här metoden för VBScript eller PowerShell.

  2. Kontrollera om den metod som du vill köra implementeras.

    Vissa klasser har metoder definierade som inte stöds av en provider. Om en metod inte implementeras kan du inte köra den. Du kan avgöra om en metod är implementerad genom att kontrollera om metoden har kvalificeraren Implementerad. Mer information finns i WMI-kvalificerare och Åtkomst till en WMI-kvalificerare. Du kan också avgöra om en providerklassmetod har Implementerad-kvalificerare inställd, genom att använda det osupporterade verktyget Wbemtest.exe, som är tillgängligt på alla operativsystem med WMI installerat.

  3. Kontrollera om den metod som du vill köra är en statisk metod eller en icke-statisk metod.

    Statiska metoder gäller endast för WMI-klasser och inte för specifika instanser av en klass. Till exempel är metoden Create i klassen Win32_Process en statisk metod eftersom den används för att skapa en ny process utan en instans av den här klassen. Icke-statiska metoder gäller endast för instanser av en klass. Metoden Avsluta i klassen Win32_Process är till exempel en icke-statisk metod eftersom det bara är meningsfullt att avsluta en process om det finns en instans av den processen. Du kan avgöra om en metod är statisk genom att kontrollera om Static-kvalificeraren är associerad med metoden.

  4. Hämta klassen eller instansen som innehåller den metod som du vill köra.

    Mer information finns i Hämta WMI-klass eller instansdata.

  5. Konfigurera eventuella säkerhetsinställningar som metoden kan kräva.

    Du kan ofta fastställa de behörigheter som en metod kräver genom att undersöka värdena i Privileges-kvalificeraren för metoden. Till exempel kräver Win32_OperatingSystem-klassen Shutdown-metoden att du ställer in behörigheten "SeShutdownPrivilege". För mer information, se Utföra privilegierade operationer.

  6. Anropa metoden och granska returvärdet för att avgöra om metoden lyckades.

I följande kodexempel skapas en Anteckningar-process och process-ID:t hämtas med direkt åtkomst.

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

Följande procedur beskriver hur du anropar en providermetod med hjälp av API:et för skript och SWbemServices.ExecMethod.

Anropa en providermetod med hjälp av Skript-API:et och SWbemServices.ExecMethod

  1. Hämta WMI-klassdefinitionen för att köra en statisk metod. Hämta WMI-klassinstansen för att köra en icke-statisk metod.
  2. Hämta metoden som ska köras från SWbemObject.Methods_ samling av din klass eller instans med hjälp av metoden SWbemObjectSet.Item.
  3. Hämta ett InParameters-objekt för metoden och konfigurera parametrarna enligt beskrivningen i Skapa InParameters-objekt.
  4. Anropa metoden SWbemServices.ExecMethod för att köra och tilldela returvärdet till ett SWbemObject- objekt för att lagra utdataparametrarna.
  5. Kontrollera värdena i objektet för utdataparametrar för att kontrollera att metoden kördes korrekt.

Följande VBScript-kodexempel utför samma åtgärd som föregående skript med den indirekta metoden genom att anropa 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

Följande procedur beskriver hur du anropar en providermetod med hjälp av C++.

Anropa en providermetod med C++

  1. Anslut till WMI.

    Om du vill anropa en metod i WMI måste du först ha en fungerande anslutning till ett WMI-namnområde. Mer information finns i Skapa ett WMI-program med C++ och Initiera COM för ett WMI-program.

    I följande exempel visas hur du ansluter till WMI. Mer information om säkerhetsproblem i WMI-provideranrop finns i Underhåll av WMI-säkerhet.

    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. Anropa IWbemServices::GetObject för att hämta definitionen av klassen för den metod som du vill anropa.

    Metoden GetObject returnerar en IWbemClassObject- pekare som pekar på klassdefinitionen.

    hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL);
  1. För metoder som kräver indataparametrar anropar du metoden IWbemClassObject::GetMethod för att hämta indataparameterklassobjektet.

    GetMethod returnerar en IWbemClassObject- pekare som pekar på indataparameterklassen.

    hr = pClass->GetMethod(MethodName, 0, &pInClass, NULL);
  1. Generera en instans av indataparameterklassen med ett anrop till metoden IWbemClassObject::SpawnInstance.
    hr = pInClass->SpawnInstance(0, &pInInst);
  1. Ange egenskaperna för indataparameterklassen med ett anrop till metoden IWbemClassObject::Put.
    VARIANT var;
    var.vt = VT_BSTR;
    var.bstrVal= SysAllocString(L"hello");
    hr = pInInst->Put(ArgName, 0, &var, 0);
    VariantClear(&var);
  1. Anropa metoden med ett anrop till IWbemServices::ExecMethod eller IWbemServices::ExecMethodAsync.

    För ExecMethodreturnerar WMI alla utdataparametrar i anropet. För ExecMethodAsync-returnerar WMI alla utdataparametrar via ett anrop till IWbemObjectSink. Mer information finns i Så här anropar du en metod.

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

Följande kod är ett fullständigt exempel för att anropa en providermetod.

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

Anropar en metod