Appel d’une méthode de fournisseur

Une méthode de fournisseur est une méthode implémentée par un fournisseur Windows Management Instrumentation (WMI). La méthode se trouve dans une classe définie par un fournisseur pour représenter les données du logiciel ou du matériel. Par exemple, la classe Win32_Service a des méthodes pour démarrer, arrêter, reprendre, suspendre et modifier les services.

Les méthodes de fournisseur ne doivent pas être confondues avec les types de méthodes suivants :

Appel d’une méthode de fournisseur à l’aide d’un script

Tout langage d’automatisation, tel que VBScript, PowerShell ou Perl, peut appeler une méthode WMI. Certaines langues peuvent utiliser l’accès direct, mais d’autres doivent utiliser SWbemServices.ExecMethod pour exécuter indirectement la méthode du fournisseur.

La procédure suivante décrit comment appeler une méthode de fournisseur à l’aide de l’API Scripting et de l’accès direct.

Pour appeler une méthode de fournisseur à l’aide de l’API Scripting et de l’accès direct

  1. Utilisez cette approche pour VBScript ou PowerShell.

  2. Déterminez si la méthode que vous souhaitez exécuter est implémentée.

    Certaines classes ont des méthodes définies qui ne sont pas prises en charge par un fournisseur. Si aucune méthode n’est implémentée, vous ne pouvez pas l’exécuter. Vous pouvez déterminer si une méthode est implémentée en vérifiant si la méthode a le qualificateur Implémenté. Pour plus d’informations, consultez Qualificateurs WMI et Accès à un qualificateur WMI. Vous pouvez également déterminer si une méthode de classe de fournisseur a le qualificateur Implémenté en exécutant l’utilitaire de Wbemtest.exe non pris en charge, disponible sur n’importe quel système d’exploitation sur lequel WMI est installé.

  3. Déterminez si la méthode que vous souhaitez exécuter est une méthode statique ou non statique.

    Les méthodes statiques s’appliquent uniquement aux classes WMI et non aux instances spécifiques d’une classe. Par exemple, la méthode Create de la classe Win32_Process est une méthode statique, car elle est utilisée pour créer un processus sans une instance de cette classe. Les méthodes non statiques s’appliquent uniquement aux instances d’une classe. Par exemple, la méthode Terminate de la classe Win32_Process est une méthode non statique, car il n’est judicieux d’arrêter un processus que si une instance de ce processus existe. Vous pouvez déterminer si une méthode est statique en vérifiant si le qualificateur Static est associé à la méthode.

  4. Récupérez la classe ou l’instance qui contient la méthode que vous souhaitez exécuter.

    Pour plus d’informations, consultez Récupération de données de classe ou d’instance WMI.

  5. Configurez tous les paramètres de sécurité dont la méthode peut avoir besoin.

    Vous pouvez souvent déterminer les privilèges requis par une méthode en examinant les valeurs dans le qualificateur Privileges de la méthode. Par exemple, la méthode Shutdown de la classe Win32_OperatingSystem vous oblige à définir le privilège « SeShutdownPrivilege ». Pour plus d’informations, consultez Exécution d’opérations privilégiées.

  6. Appelez la méthode et examinez la valeur de retour pour déterminer si la méthode a réussi.

L’exemple de code suivant crée un processus bloc-notes et obtient l’ID de processus à l’aide de l’accès direct.

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 procédure suivante décrit comment appeler une méthode de fournisseur à l’aide de l’API Scripting et de SWbemServices.ExecMethod.

Pour appeler une méthode de fournisseur à l’aide de l’API Scripting et de SWbemServices.ExecMethod

  1. Récupérez la définition de classe WMI pour exécuter une méthode statique. Récupérez l’instance de la classe WMI pour exécuter une méthode non statique.
  2. Récupérez la méthode à exécuter à partir de la collection SWbemObject.Methods_ de votre classe ou de votre instance à l’aide de la méthode SWbemObjectSet.Item.
  3. Obtenez un objet InParameters pour la méthode et configurez les paramètres comme décrit dans Construction d’objets InParameters.
  4. Appelez la méthode SWbemServices.ExecMethod pour exécuter et affectez la valeur de retour à un objet SWbemObject pour stocker les paramètres de sortie.
  5. Vérifiez les valeurs dans l’objet paramètres de sortie pour vérifier que la méthode s’est exécutée correctement.

L’exemple de code VBScript suivant effectue la même opération que le script précédent par l’approche indirecte en appelant 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 procédure suivante décrit comment appeler une méthode de fournisseur à l’aide de C++.

Pour appeler une méthode de fournisseur à l’aide de C++

  1. Connectez-vous à WMI.

    Pour appeler une méthode dans WMI, vous devez d’abord disposer d’une connexion opérationnelle à un espace de noms WMI. Pour plus d’informations, consultez Création d’une application WMI à l’aide de C++ et Initialisation de COM pour une application WMI.

    L’exemple suivant montre comment se connecter à WMI. Pour plus d’informations sur les problèmes de sécurité dans les appels de fournisseurs WMI, consultez Maintenance de la sécurité 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. Appelez IWbemServices::GetObject pour récupérer la définition de la classe de la méthode que vous souhaitez appeler.

    La méthode GetObject retourne un pointeur IWbemClassObject qui pointe vers la définition de classe.

    hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL);
  1. Pour les méthodes qui nécessitent des paramètres d’entrée, appelez la méthode IWbemClassObject::GetMethod pour obtenir l’objet de classe de paramètre d’entrée.

    GetMethod retourne un pointeur IWbemClassObject qui pointe vers la classe de paramètre d’entrée.

    hr = pClass->GetMethod(MethodName, 0, &pInClass, NULL);
  1. Générez une instance de la classe de paramètre d’entrée avec un appel à la méthode IWbemClassObject::SpawnInstance.
    hr = pInClass->SpawnInstance(0, &pInInst);
  1. Définissez les propriétés de la classe de paramètre d’entrée avec un appel à la méthode IWbemClassObject::P ut.
    VARIANT var;
    var.vt = VT_BSTR;
    var.bstrVal= SysAllocString(L"hello");
    hr = pInInst->Put(ArgName, 0, &var, 0);
    VariantClear(&var);
  1. Appelez la méthode avec un appel à IWbemServices::ExecMethod ou IWbemServices::ExecMethodAsync.

    Pour ExecMethod, WMI retourne tous les paramètres de sortie dans l’appel. Pour ExecMethodAsync, WMI retourne tous les paramètres de sortie via un appel à IWbemObjectSink. Pour plus d’informations, consultez Appel d’une méthode.

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

Le code suivant est un exemple complet d’appel d’une méthode de fournisseur.

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

Appel d’une méthode