如何读取使用C ++使用WQL检索的日志文件的内容

时间:2018-01-31 14:35:20

标签: wmi wmi-query

我是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

1 个答案:

答案 0 :(得分:2)

这是因为查询不具有您要查询的属性。如果您运行GetNames方法并打印属性名称,则会得到与此类似的结果,

Category
CategoryString
ComputerName
Data
EventCode
EventIdentifier
EventType
InsertionStrings
Logfile
Message
RecordNumber
SourceName
TimeGenerated
TimeWritten
Type
User

您只能访问这些属性。如您所见,没有名为ID的属性,因此您将获得垃圾值。希望这会有所帮助!