我是WMI的新手。我试图实现一个java应用程序,它从用户那里获取WQL查询并使用c ++本机程序执行查询,我使用JNI从java应用程序调用该程序。我设法进行WMI调用并检索数据。 我的问题是我无法读取检索到的对象的所有内容。我读了一个日志文件,其标题和一个条目是一个跟随。 标题
"Message","Id","Version","Qualifiers","Level","Task","Opcode","Keywords","RecordId","ProviderName","ProviderId","LogName","ProcessId","ThreadId","MachineName","UserId","TimeCreated","ActivityId","RelatedActivityId","ContainerLog","MatchedQueryIds","Bookmark","LevelDisplayName","OpcodeDisplayName","TaskDisplayName","KeywordsDisplayNames","Properties"
单一条目:(我将日志文件转换为csv文件只是为了查看内容)
"Windows service started.","2",,"4","5","0",,"36028357018723968","98","DigitalDelivery",,"Dell",,,"vignesh",,"14-01-2018 11:06:35",,,"c:\windows.old\windows\system32\winevt\logs\dell.evtx","System.UInt32[]","System.Diagnostics.Eventing.Reader.EventBookmark","Information","Info",,"System.Collection.ObjectModel.ReadOnlyCollection`1[System.String]","SystemCollections.Generic.List`[System.Diagnostics.EventingReader.EventProperty]"
c ++ prgram 连接到WMI
#define _WIN32_DCOM
#include <iostream>
using namespace std ;
#include <wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
#include <windows.h>
#include <jni.h>
#include "WmiClientClassTwo.h"
#include <comdef.h>
JNIEXPORT void JNICALL Java_WmiClientClassTwo_createConnection(JNIEnv *env, jobject obj,jstring jquery)
{
const char *Cquery = env->GetStringUTFChars(jquery,NULL);
cout << "query string is :::" << Cquery << endl ;
// Initializing the COM
HRESULT hr ;
hr = CoInitializeEx( 0 , COINIT_MULTITHREADED );
if(FAILED(hr))
{
cout << "failed to initialize COM Library " << hex << hr << endl ;
return;
}
//Initialize COM security
hr = CoInitializeSecurity (
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL
);
if(FAILED(hr))
{
cout << "failed to initilize security."<< hex << hr << endl ;
CoUninitialize();
return ;
}
cout << "Initilized the COM"<< endl ;
//Initializing the IWbemLocator throught a call to CoCreateInstance.
IWbemLocator *pLoc = 0 ;
hr = CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,IID_IWbemLocator,(LPVOID*) & pLoc);
if(FAILED(hr))
{
cout << "failed to create IWbemLocator object"<< hex << hr << endl ;
CoUninitialize();
return ;
}
//Connect to WMI through a call to ConnectServer method of IWbemLocator
IWbemServices *pSvc = 0 ;
hr = pLoc->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"),
NULL,
NULL,
0,
NULL,
0,
0,
&pSvc);
if(FAILED(hr))
{
cout << "could not connect to WMI from ConnectServer method"<<hex<<hr<<endl;
pLoc->Release();
CoUninitialize();
return ;
}
cout << "Connected to WMI" << endl ;
//Setting security level on a Wmi connection
hr = 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(hr))
{
cout << "could not set security level on wmi connection" << hex << hr << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return ;
}
cout << "Security level set on wmi connection" << endl;
// Querying for data using executeQuery Method of IWbemServies pointer
IEnumWbemClassObject* pEnumerator = NULL ;
hr = pSvc->ExecQuery (
bstr_t("WQL"),
// bstr_t("SELECT * FROM Win32_NTLogEvent Where (Logfile = 'Dell')"),
bstr_t(Cquery),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
if(FAILED(hr))
{
cout << "Query for operating system failed" << hex << endl ;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return ;
}
cout << "data is obtained from the operating system" << endl ;
//Getting the data from the query
IWbemClassObject *pclsobj = NULL ;
ULONG uReturn = 0 ;
while (pEnumerator)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE,1,&pclsobj,&uReturn);
if( 0 == uReturn )
{
cout << "loop broke" << endl ;
break;
}
VARIANT vtProp;
hr = pclsobj->Get(L"Message",0,&vtProp,0,0);
wcout << "Message : " << vtProp.bstrVal << endl ;
VariantClear(&vtProp);
hr = pclsobj->Get(L"ComputerName",0,&vtProp,0,0);
wcout << "ComputerName : " << vtProp.bstrVal << endl;
VariantClear(&vtProp);
hr = pclsobj->Get(L"Id",0,&vtProp,0,0);
wcout << "Id : " << vtProp.plVal << endl ;
VariantClear(&vtProp);
hr = pclsobj->Get(L"ProviderName",0,&vtProp,0,0);
wcout << "ProviderName : " << vtProp.bstrVal << endl ;
VariantClear(&vtProp);
hr = pclsobj->Get(L"Level",0,&vtProp,0,0);
wcout << "Level : " << vtProp.plVal << endl ;
VariantClear(&vtProp);
pclsobj->Release();
}
pSvc->Release();
pLoc->Release();
pEnumerator->Release();
CoUninitialize();
return ;
}
当我执行程序时,只有Message和Computername属性返回正确的值,而所有其他字段都返回错误的值。 任何人都可以告诉我如何读取检索到的日志文件中的所有字段。 我获得的单个条目的样本输出是 的输出:
SELECT * FROM Win32_NTLogEvent Where (Logfile = 'Dell')
query string is :::SELECT * FROM Win32_NTLogEvent Where (Logfile = 'Dell')
Initilized the COM
Connected to WMI
Security level set on wmi connection
data is obtained from the operating system
Message : Windows service started.
ComputerName : vignesh
Id : 0000000000E93A88
ProviderName : vignesh
0
Level : 0000000000000000
TimeCreated : 0000000000EA1798
答案 0 :(得分:2)
这是因为查询不具有您要查询的属性。如果您运行GetNames方法并打印属性名称,则会得到与此类似的结果,
Category
CategoryString
ComputerName
Data
EventCode
EventIdentifier
EventType
InsertionStrings
Logfile
Message
RecordNumber
SourceName
TimeGenerated
TimeWritten
Type
User
您只能访问这些属性。如您所见,没有名为ID的属性,因此您将获得垃圾值。希望这会有所帮助!