Przykład: wywoływanie metody dostawcy
W tym temacie można użyć procedury i przykładów kodu, aby utworzyć pełną aplikację kliencką usługi WMI, która wykonuje inicjowanie modelu COM, łączy się z usługą WMI na komputerze lokalnym, wywołuje metodę dostawcy, a następnie czyści. Metoda Win32_Process::Create służy do uruchamiania Notepad.exe w nowym procesie.
Poniższa procedura służy do wykonywania aplikacji WMI. Kroki od 1 do 5 zawierają wszystkie kroki wymagane do skonfigurowania i nawiązania połączenia z usługą WMI, a 6 to miejsce, w którym wywoływana jest metoda dostawcy.
Aby wywołać metodę dostawcy
Zainicjuj parametry MODELU COM za pomocą wywołania polecenia CoInitializeEx.
Aby uzyskać więcej informacji, zobacz Inicjowanie modelu COM dla aplikacji WMI.
Zainicjuj zabezpieczenia procesu COM, wywołując CoInitializeSecurity.
Aby uzyskać więcej informacji, zobacz Ustawianie domyślnego poziomu zabezpieczeń procesu przy użyciu języka C++.
Uzyskaj początkowy lokalizator do usługi WMI, wywołując CoCreateInstance.
Aby uzyskać więcej informacji, zobacz Tworzenie połączenia z przestrzenią nazw usługi WMI.
Uzyskaj wskaźnik IWbemServices dla przestrzeni nazw root\cimv2 na komputerze lokalnym, wywołując IWbemLocator::ConnectServer. Aby nawiązać połączenie z komputerem zdalnym, zobacz Przykład: Pobieranie danych WMI z komputera zdalnego.
Aby uzyskać więcej informacji, zobacz Tworzenie połączenia z przestrzenią nazw usługi WMI.
Ustaw zabezpieczenia serwera proxy IWbemServices, aby usługa WMI mogła personifikować klienta, wywołując coSetProxyBlanket.
Aby uzyskać więcej informacji, zobacz Ustawianie poziomów zabezpieczeń w połączeniu usługi WMI.
Użyj wskaźnika IWbemServices, aby wysyłać żądania do usługi WMI. W tym przykładzie użyto IWbemServices::ExecMethod wywołania metody dostawcy Win32_Process::Create.
Aby uzyskać więcej informacji na temat podejmowania żądań do usługi WMI, zobacz Manipulowanie informacjami o klasie i wystąpieniu oraz Wywoływanie metody.
Jeśli metoda dostawcy ma jakiekolwiek parametry in-parameters lub out-parameters, wartości parametrów muszą być podane IWbemClassObject wskaźników. W przypadku parametrów w parametrach należy zduplikować wystąpienie definicji parametrów, a następnie ustawić wartości tych nowych wystąpień. Metoda Win32_Process::Create wymaga prawidłowego wykonania polecenia CommandLine w parametrze .
Poniższy przykład kodu tworzy wskaźnik IWbemClassObject, powoduje utworzenie nowego wystąpienia Win32_Process::Create w definicjach parametrów, a następnie ustawienie wartości parametru CommandLine w parametrze na wartość Notepad.exe.
// Set up to call the Win32_Process::Create method BSTR MethodName = SysAllocString(L"Create"); BSTR ClassName = SysAllocString(L"Win32_Process"); IWbemClassObject* pClass = NULL; hres = pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL); IWbemClassObject* pInParamsDefinition = NULL; hres = pClass->GetMethod(MethodName, 0, &pInParamsDefinition, NULL); IWbemClassObject* pClassInstance = NULL; hres = pInParamsDefinition->SpawnInstance(0, &pClassInstance); // Create the values for the in-parameters VARIANT varCommand; varCommand.vt = VT_BSTR; varCommand.bstrVal = _bstr_t(L"notepad.exe"); // Store the value for the in-parameters hres = pClassInstance->Put(L"CommandLine", 0, &varCommand, 0); wprintf(L"The command is: %s\n", V_BSTR(&varCommand));
Poniższy przykład kodu pokazuje, jak Win32_Process::Create parametrów out-parameters są podane do wskaźnika IWbemClassObject. Wartość parametru out jest uzyskiwana za pomocą metody IWbemClassObject::Get i przechowywana w zmiennej VARIANT, aby była wyświetlana użytkownikowi.
// Execute Method IWbemClassObject* pOutParams = NULL; hres = pSvc->ExecMethod(ClassName, MethodName, 0, NULL, pClassInstance, &pOutParams, NULL); VARIANT varReturnValue; hres = pOutParams->Get(_bstr_t(L"ReturnValue"), 0, &varReturnValue, NULL, 0);
Poniższy przykład kodu pokazuje, jak wywołać metodę dostawcy przy użyciu usługi WMI.
#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <comdef.h>
#include <Wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
int main(int iArgCnt, char ** argv)
{
HRESULT hres;
// Step 1: --------------------------------------------------
// Initialize COM. ------------------------------------------
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres))
{
cout << "Failed to initialize COM library. Error code = 0x"
<< hex << hres << endl;
return 1; // Program has failed.
}
// Step 2: --------------------------------------------------
// Set general COM security levels --------------------------
hres = CoInitializeSecurity(
NULL,
-1, // COM negotiates service
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL // Reserved
);
if (FAILED(hres))
{
cout << "Failed to initialize security. Error code = 0x"
<< hex << hres << endl;
CoUninitialize();
return 1; // Program has failed.
}
// Step 3: ---------------------------------------------------
// Obtain the initial locator to WMI -------------------------
IWbemLocator *pLoc = NULL;
hres = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *) &pLoc);
if (FAILED(hres))
{
cout << "Failed to create IWbemLocator object. "
<< "Err code = 0x"
<< hex << hres << endl;
CoUninitialize();
return 1; // Program has failed.
}
// Step 4: ---------------------------------------------------
// Connect to WMI through the IWbemLocator::ConnectServer method
IWbemServices *pSvc = NULL;
// Connect to the local root\cimv2 namespace
// and obtain pointer pSvc to make IWbemServices calls.
hres = pLoc->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"),
NULL,
NULL,
0,
NULL,
0,
0,
&pSvc
);
if (FAILED(hres))
{
cout << "Could not connect. Error code = 0x"
<< hex << hres << endl;
pLoc->Release();
CoUninitialize();
return 1; // Program has failed.
}
cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;
// Step 5: --------------------------------------------------
// Set security levels for the proxy ------------------------
hres = CoSetProxyBlanket(
pSvc, // Indicates the proxy to set
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hres))
{
cout << "Could not set proxy blanket. Error code = 0x"
<< hex << hres << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return 1; // Program has failed.
}
// Step 6: --------------------------------------------------
// Use the IWbemServices pointer to make requests of WMI ----
// set up to call the Win32_Process::Create method
BSTR MethodName = SysAllocString(L"Create");
BSTR ClassName = SysAllocString(L"Win32_Process");
IWbemClassObject* pClass = NULL;
hres = pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL);
IWbemClassObject* pInParamsDefinition = NULL;
hres = pClass->GetMethod(MethodName, 0,
&pInParamsDefinition, NULL);
IWbemClassObject* pClassInstance = NULL;
hres = pInParamsDefinition->SpawnInstance(0, &pClassInstance);
// Create the values for the in parameters
VARIANT varCommand;
varCommand.vt = VT_BSTR;
varCommand.bstrVal = _bstr_t(L"notepad.exe");
// Store the value for the in parameters
hres = pClassInstance->Put(L"CommandLine", 0,
&varCommand, 0);
wprintf(L"The command is: %s\n", V_BSTR(&varCommand));
// Execute Method
IWbemClassObject* pOutParams = NULL;
hres = pSvc->ExecMethod(ClassName, MethodName, 0,
NULL, pClassInstance, &pOutParams, NULL);
if (FAILED(hres))
{
cout << "Could not execute method. Error code = 0x"
<< hex << hres << endl;
VariantClear(&varCommand);
SysFreeString(ClassName);
SysFreeString(MethodName);
pClass->Release();
pClassInstance->Release();
pInParamsDefinition->Release();
pOutParams->Release();
pSvc->Release();
pLoc->Release();
CoUninitialize();
return 1; // Program has failed.
}
// To see what the method returned,
// use the following code. The return value will
// be in &varReturnValue
VARIANT varReturnValue;
hres = pOutParams->Get(_bstr_t(L"ReturnValue"), 0,
&varReturnValue, NULL, 0);
// Clean up
//--------------------------
VariantClear(&varCommand);
VariantClear(&varReturnValue);
SysFreeString(ClassName);
SysFreeString(MethodName);
pClass->Release();
pClassInstance->Release();
pInParamsDefinition->Release();
pOutParams->Release();
pLoc->Release();
pSvc->Release();
CoUninitialize();
return 0;
}