Chiamata a un metodo provider

Un metodo provider è un metodo implementato da un provider wmi (Windows Management Instrumentation). Il metodo si trova in una classe definita da un provider per rappresentare i dati dal software o dall'hardware. Ad esempio, la classe Win32_Service include metodi per avviare, arrestare, riprendere, sospendere e modificare i servizi.

I metodi del provider non devono essere confusi con i tipi di metodi seguenti:

Chiamata di un metodo provider tramite scripting

Qualsiasi linguaggio di automazione, ad esempio VBScript, PowerShell o Perl, può chiamare un metodo WMI. Alcuni linguaggi possono usare l'accesso diretto, ma altri devono usare SWbemServices.ExecMethod per eseguire indirettamente il metodo del provider.

La procedura seguente descrive come chiamare un metodo del provider usando l'API di scripting e l'accesso diretto.

Per chiamare un metodo del provider usando l'API di scripting e l'accesso diretto

  1. Usare questo approccio per VBScript o PowerShell.

  2. Determinare se il metodo da eseguire è implementato.

    Alcune classi hanno metodi definiti che non sono supportati da un provider. Se un metodo non è implementato, non è possibile eseguirlo. È possibile determinare se un metodo viene implementato controllando se il metodo dispone del qualificatore Implementato . Per altre informazioni, vedere Qualificatori WMI e Accesso a un qualificatore WMI. È anche possibile determinare se un metodo della classe provider ha il qualificatore Implementato impostato eseguendo l'utilità Wbemtest.exe non supportata, disponibile in qualsiasi sistema operativo con WMI installato.

  3. Determinare se il metodo da eseguire è un metodo statico o un metodo non statico.

    I metodi statici si applicano solo alle classi WMI e non a istanze specifiche di una classe. Ad esempio, il metodo Create della classe Win32_Process è un metodo statico perché viene usato per creare un nuovo processo senza un'istanza di questa classe. I metodi non statico si applicano solo alle istanze di una classe. Ad esempio, il metodo Terminate della classe Win32_Process è un metodo non statico perché ha senso terminare un processo solo se esiste un'istanza di tale processo. È possibile determinare se un metodo è statico controllando se il qualificatore statico è associato al metodo .

  4. Recuperare la classe o l'istanza che contiene il metodo da eseguire.

    Per altre informazioni, vedere Recupero di dati di istanza o classe WMI.

  5. Configurare le impostazioni di sicurezza che il metodo potrebbe richiedere.

    È spesso possibile determinare i privilegi richiesti da un metodo esaminando i valori nel qualificatore Privileges del metodo . Ad esempio, il metodo Shutdowndella classe Win32_OperatingSystem richiede di impostare il privilegio "SeShutdownPrivilege". Per altre informazioni, vedere Esecuzione di operazioni con privilegi.

  6. Chiamare il metodo ed esaminare il valore restituito per determinare se il metodo ha avuto esito positivo.

L'esempio di codice seguente crea un processo blocco note e ottiene l'ID processo usando l'accesso diretto.

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

La procedura seguente descrive come chiamare un metodo del provider usando l'API di scripting e SWbemServices.ExecMethod.

Per chiamare un metodo provider usando l'API di scripting e SWbemServices.ExecMethod

  1. Recuperare la definizione della classe WMI per eseguire un metodo statico. Recuperare l'istanza della classe WMI per eseguire un metodo non statico.
  2. Recuperare il metodo da eseguire dalla raccolta SWbemObject.Methods_ della classe o dell'istanza usando il metodo SWbemObjectSet.Item .
  3. Ottenere un oggetto InParameters per il metodo e configurare i parametri come descritto in Costruzione di oggetti InParameters.
  4. Chiamare il metodo SWbemServices.ExecMethod per eseguire e assegnare il valore restituito a un oggetto SWbemObject per archiviare i parametri di output.
  5. Controllare i valori nell'oggetto parametri di output per verificare che il metodo sia stato eseguito correttamente.

Nell'esempio di codice VBScript seguente viene eseguita la stessa operazione dello script precedente tramite l'approccio indiretto tramite la chiamata a 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

La procedura seguente descrive come chiamare un metodo del provider usando C++.

Per chiamare un metodo del provider tramite C++

  1. Connettersi a WMI.

    Per chiamare un metodo in WMI, è prima necessario avere una connessione funzionante a uno spazio dei nomi WMI. Per altre informazioni, vedere Creazione di un'applicazione WMI tramite C++ e inizializzazione di COM per un'applicazione WMI.

    Nell'esempio seguente viene illustrato come connettersi a WMI. Per altre informazioni sui problemi di sicurezza nelle chiamate al provider WMI, vedere Gestione della sicurezza 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. Chiamare IWbemServices::GetObject per recuperare la definizione della classe del metodo che si desidera chiamare.

    Il metodo GetObject restituisce un puntatore IWbemClassObject che punta alla definizione della classe.

    hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL);
  1. Per i metodi che richiedono parametri di input, chiamare il metodo IWbemClassObject::GetMethod per ottenere l'oggetto classe del parametro di input.

    GetMethod restituisce un puntatore IWbemClassObject che punta alla classe del parametro di input.

    hr = pClass->GetMethod(MethodName, 0, &pInClass, NULL);
  1. Generare un'istanza della classe del parametro di input con una chiamata al metodo IWbemClassObject::SpawnInstance .
    hr = pInClass->SpawnInstance(0, &pInInst);
  1. Impostare le proprietà della classe di parametri di input con una chiamata al metodo IWbemClassObject::P ut .
    VARIANT var;
    var.vt = VT_BSTR;
    var.bstrVal= SysAllocString(L"hello");
    hr = pInInst->Put(ArgName, 0, &var, 0);
    VariantClear(&var);
  1. Richiamare il metodo con una chiamata a IWbemServices::ExecMethod o IWbemServices::ExecMethodAsync.

    Per ExecMethod, WMI restituisce tutti i parametri di output nella chiamata. Per ExecMethodAsync, WMI restituisce tutti i parametri di output tramite una chiamata a IWbemObjectSink. Per altre informazioni, vedere Chiamata di un metodo.

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

Il codice seguente è un esempio completo per chiamare un metodo provider.

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

Chiamata di un metodo