积极答复者
关于win32使用com编程的问题

问题
-
如以下代码,查询不同的字段,经常会在 HRESULT hr = pEnumerator->Next( WBEM_INFINITE, 1, &pclsObj, &uReturn ); 这句报出异常,读取0x....错误,该如何处理呢?
#include "stdafx.h"
#define _WIN32_DCOM
#include <atlcomcli.h>
//#include <iostream>
using namespace std;
#include <comdef.h>
#include <Wbemidl.h>
#include "wing_string.h"
# pragma comment(lib, "wbemuuid.lib")
class WingWmic{
private:
IWbemServices *pSvc;
int has_error;
IEnumWbemClassObject* pEnumerator;
IWbemLocator *pLoc;
char *query_table;
public:
WingWmic();
~WingWmic();
void query( const char *sql );
BOOL next();
char* get( const char *key);
};
WingWmic::WingWmic(){
this->pSvc = NULL;
this->pEnumerator = NULL;
this->has_error = 0;
this->pLoc = NULL;
this->query_table = NULL;
HRESULT hres;
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres))
{
this->has_error = 1;
return;
}
hres = CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL );
if (FAILED(hres))
{
this->has_error = 1;
return ;
}
hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc );
if (FAILED(hres))
{
this->has_error = 1;
return ;
}
hres = pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &this->pSvc );
if (FAILED(hres))
{
this->has_error = 1;
return ;
}
hres = CoSetProxyBlanket( pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );
if (FAILED(hres))
{
this->has_error = 1;
return;
}
}
WingWmic::~WingWmic(){
if( pSvc != NULL )
pSvc->Release();
if( pLoc != NULL )
pLoc->Release();
if( pEnumerator != NULL )
pEnumerator->Release();
if( this->query_table != NULL )
delete[] this->query_table;
CoUninitialize();
}
void WingWmic::query( const char* _sql ){
if( this->has_error ) return;
char *sql = _strdup( _sql );
int i = 0;
while( sql[i] != '\0' ){
sql[i] = tolower(sql[i]);
i++;
}
char *from = strstr( sql , "from" )+4;
while( 1 ) {
char c = *from;
if( !isspace(c) ) break;
from++;
}
this->query_table = new char[32];
memset( this->query_table , 0 , 32);
int index = 0;
while(1) {
char c = *from;
if( isspace(c) || c == '\0' ) break;
this->query_table[index] = c;
index++;
from++;
}
//printf("table=%s\r\n",this->query_table);
HRESULT hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t(sql),WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL,&this->pEnumerator);
if (FAILED(hres))
{
this->has_error = 1;
}
delete[] sql;
}
BOOL WingWmic::next(){
return !!pEnumerator;
}
char* WingWmic::get( const char *key){
SetLastError(0);
if( this->has_error )
{
//printf("has error %ld\r\n",GetLastError());
pEnumerator->Release();
pEnumerator = NULL;
return NULL;
}
IWbemClassObject *pclsObj = NULL;
ULONG uReturn = 0;
HRESULT hr = pEnumerator->Next( WBEM_INFINITE, 1, &pclsObj, &uReturn );
if( 0 == uReturn )
{
//printf("\r\nfail %ld\r\n",GetLastError());
if( pclsObj != NULL ) {
pclsObj->Release();
pclsObj=NULL;
}
pEnumerator->Release();
pEnumerator = NULL;
return NULL;
}
VARIANT vtProp;
wchar_t *wkey = wing_str_char_to_wchar( key );
hr = pclsObj->Get( wkey , 0, &vtProp, 0, 0);
//wcout<<"key=>"<<wkey<<"<=="<<endl;
char *res = NULL;
if( SUCCEEDED( hr ) && vtProp.bstrVal )
{
res = wing_str_wchar_to_char( (const wchar_t*)vtProp.bstrVal );
}else{
//wcout<<"fail key=>"<<wkey<<endl;
}
VariantClear(&vtProp);
if( pclsObj != NULL ) {
pclsObj->Release();
pclsObj=NULL;
}
return res;
}
int _tmain(int argc, _TCHAR* argv[])
{
char sql[] = "SELECT * FROM Win32_Process\0";
//char *sql = "SELECT * FROM Win32_Processor";
WingWmic mic;
mic.query(sql);
int count = 1;
char *c = NULL;
while( mic.next() ) {
c = mic.get("CommandLine");
printf("CommandLine:%ld=>%s\r\n",count,c);
count++;
}
return 0;
}
答案
-
Hi 吉利儿,
感谢在MSDN论坛发帖。
WingWmic 是你自己的类吗? 请提供一些具体的实现。
你的问题出在你没有对pEnumerator进行赋值。导致空指针调用。请使用一下代码对其进行赋值或将代码添加到你的mic.query实现中。
IEnumWbemClassObject* pEnumerator = NULL; hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * FROM Win32_OperatingSystem"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
希望对你有所帮助。
Best Regards,
Sera Yu
We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
全部回复
-
像这样调用
int _tmain(int argc, _TCHAR* argv[])
{
char sql[] = "SELECT * FROM Win32_Process\0";
//char *sql = "SELECT * FROM Win32_Processor";
WingWmic mic;
mic.query(sql);
int count = 1;
char *c = NULL;
while( mic.next() ) {
c = mic.get("CommandLine");
printf("CommandLine:%ld=>%s\r\n",count,c);
c = mic.get("Caption");
printf("Caption:%ld=>%s\r\n",count,c);
c = mic.get("CSCreationClassName");
printf("CSCreationClassName:%ld=>%s\r\n",count,c);
count++;
}
return 0;
}
-
Hi 吉利儿,
感谢在MSDN论坛发帖。
WingWmic 是你自己的类吗? 请提供一些具体的实现。
你的问题出在你没有对pEnumerator进行赋值。导致空指针调用。请使用一下代码对其进行赋值或将代码添加到你的mic.query实现中。
IEnumWbemClassObject* pEnumerator = NULL; hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * FROM Win32_OperatingSystem"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
希望对你有所帮助。
Best Regards,
Sera Yu
We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.