2016-12-07 5 views
1

Ich versuche, die WMI-Klasse Win32_Process zu verwenden, um eine Liste der laufenden Prozesse und die Benutzer, die die Besitzer jedes Prozesses sind, zu erhalten. Die Enumeration von Prozessen, die Win32_Process in C++ verwenden, war mit dem Enumerationsbeispiel von MSDN (MSDN) und dem einfachen Ändern von Win32_OperatingSystem in Win32_Process nicht so schwierig. Ich habe herausgefunden, dass ich mit der Methode GetOwner von Win32_Process den Benutzer und die Domäne des Eigentümers eines Prozesses ermitteln kann. Es gibt ein großartiges Beispiel dafür in VB (MSDN), das zeigt, dass ich das Enumerator-Objekt verwenden kann, um die spezifische Instanz von GetOwner für die Prozessinformation an einem beliebigen Punkt in der Aufzählung aufzurufen.Verwenden von Win32_Process.GetOwner in C++

Ich habe versucht, das Codebeispiel (MSDN) für "Aufruf einer Provider-Methode" zu verwenden, um herauszufinden, wie der Methodenaufruf zu GetOwner zu machen, aber ich kann nicht herausfinden, wie Sie es zum Laufen bringen. Ich treffe immer wieder Straßensperren. Normalerweise erhalte ich die ungültigen Methodenparameter. Nehmen Sie den folgenden Code Chunk

 BSTR MethodName = SysAllocString(L"GetOwner"); 
     BSTR ClassName = SysAllocString(L"Win32_Process"); 

     IWbemClassObject* pClass = NULL; 
     hres = pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL); 
     printf("[1] hres = %08x\n", hres); 

     IWbemClassObject* pInParamsDefinition = NULL; 
     IWbemClassObject* pOutParams = NULL; 
     hres = pClass->GetMethod(MethodName, 0, &pInParamsDefinition, &pOutParams); 
     printf("[2] hres = %08x (%08x, %08x)\n", hres, pInParamsDefinition, pOutParams); 

     // Execute Method 
     hres = pSvc->ExecMethod(L"Win32_Process", MethodName, 0, NULL, NULL, &pOutParams, NULL); 

     VARIANT varReturnValue; 
     hres = pOutParams->Get(_bstr_t(L"ReturnValue"), 0, 
      &varReturnValue, NULL, 0); 
     wprintf(L"The command is: %s\n", V_BSTR(&varReturnValue)); 

GetOwner hat keine Eingabeparameter und wenn ich GetMethod die pInParamsDefinition immer wieder rufen NULL während pOutParams eine ptr zurückgibt. Da kein Zeiger auf pInParamsDefinition zurückgegeben wird, kann ich keine Eingaben liefern und weiß daher nicht, wie ich das Problem mit ungültigen Methodenparametern umgehen kann. Klar WMI-Programmierung ist nicht meine stärkste Fähigkeit :)

Was fehlt mir hier?

Antwort

0

Nachdem ich für eine Weile rumgespielt habe, habe ich endlich die Antwort auf meine Frage gefunden. Das Problem besteht darin, dass Sie angeben müssen, für welches Objekt die Methode ausgeführt werden soll. Dazu rufen Sie GetObject ("__ PATH", ...) auf, um den Pfad zu dem Objekt zu ermitteln, das gerade aufgelistet wird, und übergeben das Ergebnis von GetObject (ein BSTR) an ExecMethod als das erste Argument. Dies sagt der Methode, in meinem Fall GetOwner, was Sie ausführen möchten. Hier ist ein Beispielprogramm, das ich schrieb, das die aktuelle Liste der Prozesse und deren Besitzer ausgibt.

#define _WIN32_DCOM 
 
#include <iostream> 
 
using namespace std; 
 
#include <comdef.h> 
 
#include <Wbemidl.h> 
 

 
#pragma comment(lib, "wbemuuid.lib") 
 

 
int main(int argc, char **argv) 
 
{ 
 
\t HRESULT hres; 
 

 
\t // Step 1: -------------------------------------------------- 
 
\t // Initialize COM. ------------------------------------------ 
 

 
\t hres = CoInitializeEx(0, COINIT_MULTITHREADED); 
 
\t if (FAILED(hres)) 
 
\t { 
 
\t \t cout << "Failed to initialize COM library. Error code = 0x" 
 
\t \t \t << hex << hres << endl; 
 
\t \t return 1;     // Program has failed. 
 
\t } 
 

 
\t // Step 2: -------------------------------------------------- 
 
\t // Set general COM security levels -------------------------- 
 

 
\t hres = CoInitializeSecurity(
 
\t \t NULL, 
 
\t \t -1,       // COM authentication 
 
\t \t NULL,      // Authentication services 
 
\t \t NULL,      // Reserved 
 
\t \t RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication 
 
\t \t RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation 
 
\t \t NULL,      // Authentication info 
 
\t \t EOAC_NONE,     // Additional capabilities 
 
\t \t NULL       // Reserved 
 
\t \t); 
 

 

 
\t if (FAILED(hres)) 
 
\t { 
 
\t \t cout << "Failed to initialize security. Error code = 0x" 
 
\t \t \t << hex << hres << endl; 
 
\t \t CoUninitialize(); 
 
\t \t return 1;     // Program has failed. 
 
\t } 
 

 
\t // Step 3: --------------------------------------------------- 
 
\t // Obtain the initial locator to WMI ------------------------- 
 

 
\t IWbemLocator *pLoc = NULL; 
 

 
\t hres = CoCreateInstance(
 
\t \t CLSID_WbemLocator, 
 
\t \t 0, 
 
\t \t CLSCTX_INPROC_SERVER, 
 
\t \t IID_IWbemLocator, (LPVOID *)&pLoc); 
 

 
\t if (FAILED(hres)) 
 
\t { 
 
\t \t cout << "Failed to create IWbemLocator object." 
 
\t \t \t << " Err code = 0x" 
 
\t \t \t << hex << hres << endl; 
 
\t \t CoUninitialize(); 
 
\t \t return 1;     // Program has failed. 
 
\t } 
 

 
\t // Step 4: ----------------------------------------------------- 
 
\t // Connect to WMI through the IWbemLocator::ConnectServer method 
 

 
\t IWbemServices *pSvc = NULL; 
 

 
\t // Connect to the root\cimv2 namespace with 
 
\t // the current user and obtain pointer pSvc 
 
\t // to make IWbemServices calls. 
 
\t hres = pLoc->ConnectServer(
 
\t \t _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace 
 
\t \t NULL,     // User name. NULL = current user 
 
\t \t NULL,     // User password. NULL = current 
 
\t \t 0,      // Locale. NULL indicates current 
 
\t \t NULL,     // Security flags. 
 
\t \t 0,      // Authority (for example, Kerberos) 
 
\t \t 0,      // Context object 
 
\t \t &pSvc     // pointer to IWbemServices proxy 
 
\t \t); 
 

 
\t if (FAILED(hres)) 
 
\t { 
 
\t \t cout << "Could not connect. Error code = 0x" 
 
\t \t \t << hex << hres << endl; 
 
\t \t pLoc->Release(); 
 
\t \t CoUninitialize(); 
 
\t \t return 1;    // Program has failed. 
 
\t } 
 

 
\t cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl; 
 

 

 
\t // Step 5: -------------------------------------------------- 
 
\t // Set security levels on the proxy ------------------------- 
 

 
\t hres = CoSetProxyBlanket(
 
\t \t pSvc,      // Indicates the proxy to set 
 
\t \t RPC_C_AUTHN_WINNT,   // RPC_C_AUTHN_xxx 
 
\t \t RPC_C_AUTHZ_NONE,   // RPC_C_AUTHZ_xxx 
 
\t \t NULL,      // Server principal name 
 
\t \t RPC_C_AUTHN_LEVEL_CALL,  // RPC_C_AUTHN_LEVEL_xxx 
 
\t \t RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx 
 
\t \t NULL,      // client identity 
 
\t \t EOAC_NONE     // proxy capabilities 
 
\t \t); 
 

 
\t if (FAILED(hres)) 
 
\t { 
 
\t \t cout << "Could not set proxy blanket. Error code = 0x" 
 
\t \t \t << hex << hres << endl; 
 
\t \t pSvc->Release(); 
 
\t \t pLoc->Release(); 
 
\t \t CoUninitialize(); 
 
\t \t return 1;    // Program has failed. 
 
\t } 
 

 
\t BSTR MethodName = SysAllocString(L"GetOwner"); 
 
\t BSTR ClassName = SysAllocString(L"Win32_Process"); 
 

 
\t // get the object containing our desired method 
 
\t IWbemClassObject* pClass = NULL; 
 
\t hres = pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL); 
 
\t if (FAILED(hres)) 
 
\t { 
 
\t \t printf("GetObject hres = %08x\n", hres); 
 
\t \t pSvc->Release(); 
 
\t \t pLoc->Release(); 
 
\t \t CoUninitialize(); 
 
\t \t return 1; 
 
\t } 
 
\t 
 
\t // get the desired method 
 
\t // in our case, we only need pmethodGetOwner since GetOwner really only has output 
 
\t IWbemClassObject* pmethodGetOwner = NULL; 
 
\t hres = pClass->GetMethod(MethodName, 0, NULL, &pmethodGetOwner); 
 
\t if (FAILED(hres)) 
 
\t { 
 
\t \t printf("GetMethod hres = %08x\n", hres); 
 
\t \t pSvc->Release(); 
 
\t \t pLoc->Release(); 
 
\t \t CoUninitialize(); 
 
\t \t return 1; 
 
\t } 
 

 
\t // spawn the instance of the method 
 
\t IWbemClassObject* pInInst = NULL; 
 
\t hres = pmethodGetOwner->SpawnInstance(0, &pInInst); 
 
\t if (FAILED(hres)) 
 
\t { 
 
\t \t printf("SpawnInstance hres = %08x\n", hres); 
 
\t \t pSvc->Release(); 
 
\t \t pLoc->Release(); 
 
\t \t CoUninitialize(); 
 
\t \t return 1; 
 
\t } 
 

 
\t // Step 6: -------------------------------------------------- 
 
\t // Use the IWbemServices pointer to make requests of WMI ---- 
 

 
\t // For example, get the name of the operating system 
 
\t IEnumWbemClassObject* pEnumerator = NULL; 
 
\t hres = pSvc->ExecQuery(
 
\t \t bstr_t("WQL"), 
 
\t \t bstr_t("SELECT * FROM Win32_Process"), 
 
\t \t WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
 
\t \t NULL, 
 
\t \t &pEnumerator); 
 

 
\t if (FAILED(hres)) 
 
\t { 
 
\t \t cout << "Query for operating system name failed." 
 
\t \t \t << " Error code = 0x" 
 
\t \t \t << hex << hres << endl; 
 
\t \t pSvc->Release(); 
 
\t \t pLoc->Release(); 
 
\t \t CoUninitialize(); 
 
\t \t return 1;    // Program has failed. 
 
\t } 
 

 
\t // Step 7: ------------------------------------------------- 
 
\t // Get the data from the query in step 6 ------------------- 
 

 
\t IWbemClassObject *pclsObj = NULL; 
 
\t ULONG uReturn = 0; 
 

 
\t while (pEnumerator) 
 
\t { 
 
\t \t HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); 
 

 
\t \t if (0 == uReturn) 
 
\t \t { 
 
\t \t \t break; 
 
\t \t } 
 

 
\t \t VARIANT vtProp; 
 
\t \t VARIANT vtProcName; 
 
\t \t VARIANT vtDomain; 
 
\t \t VARIANT vtUsername; 
 

 
\t \t // Get the value of the Name property 
 
\t \t hr = pclsObj->Get(L"Name", 0, &vtProcName, 0, 0); 
 
\t \t if (FAILED(hres)) 
 
\t \t { 
 
\t \t \t printf("Failed to get the process's name\n"); 
 
\t \t \t pclsObj->Release(); 
 
\t \t \t continue; 
 
\t \t } 
 

 
\t \t // Get the PATH to the object in question 
 
\t \t // the result in vtProp is similar to '\\name_of_computer\ROOT\CIMV2:Win32_Process.Handle="pid_of_process"' 
 
\t \t hr = pclsObj->Get(L"__PATH", 0, &vtProp, 0, 0); 
 
\t \t if (FAILED(hres)) 
 
\t \t { 
 
\t \t \t printf("Failed to get the path to the object\n"); 
 
\t \t \t pclsObj->Release(); 
 
\t \t \t continue; 
 
\t \t } 
 

 
\t \t // Execute Method against the object defined by the __PATH variable 
 
\t \t hres = pSvc->ExecMethod(vtProp.bstrVal, MethodName, 0, NULL, NULL, &pmethodGetOwner, NULL); 
 
\t \t if (FAILED(hres)) 
 
\t \t { 
 
\t \t \t wprintf(L"Failed to execute the method against %s\n", vtProp.bstrVal); 
 
\t \t \t pclsObj->Release(); 
 
\t \t \t continue; 
 
\t \t } 
 

 
\t \t // extract the results 
 
\t \t hres = pmethodGetOwner->Get(L"User", 0, &vtUsername, NULL, 0); 
 
\t \t if (FAILED(hres)) 
 
\t \t { 
 
\t \t \t printf("Failed to get the owner's name\n"); 
 
\t \t \t pclsObj->Release(); 
 
\t \t \t continue; 
 
\t \t } 
 

 
\t \t pmethodGetOwner->Get(L"Domain", 0, &vtDomain, NULL, 0); 
 
\t \t if (FAILED(hres)) 
 
\t \t { 
 
\t \t \t printf("Failed to get the owner's domain\n"); 
 
\t \t \t pclsObj->Release(); 
 
\t \t \t continue; 
 
\t \t } 
 

 
\t \t // print the output to screen 
 
\t \t wprintf(L"Process: %s. Domain\\User: %s\\%s\n", V_BSTR(&vtProcName), V_BSTR(&vtDomain), V_BSTR(&vtUsername)); 
 

 
\t \t // release/cleanup resources we used this go around 
 
\t \t VariantClear(&vtProcName); 
 
\t \t VariantClear(&vtProp); 
 
\t \t VariantClear(&vtDomain); 
 
\t \t VariantClear(&vtUsername); 
 
\t \t pclsObj->Release(); 
 

 
\t } 
 

 
\t // Cleanup 
 
\t // ======== 
 

 
\t pSvc->Release(); 
 
\t pLoc->Release(); 
 
\t pEnumerator->Release(); 
 
\t CoUninitialize(); 
 

 
\t return 0; // Program successfully completed. 
 

 
}

Ich konnte all dies dank einem zufälligen Eintrag auf Google-Gruppen von 2002 ("Here is a WBem WMI C++ example") Figur.

Ich hoffe, dass dies jemand anderen in der Zukunft hilft.