【问题标题】:Query for Event Log Information of Microsoft-Windows-UniversalTelemetryClient/Operational查询 Microsoft-Windows-UniversalTelemetryClient/Operational 的事件日志信息
【发布时间】:2021-03-08 17:18:48
【问题描述】:

我阅读了this example,但在该示例中我想查询Microsoft-Windows-UniversalTelemetryClient/Operational 而不是MyEventProvider。我想使用这个事件日志来检查互联网连接。

我该怎么做?

【问题讨论】:

    标签: c++ windows event-log


    【解决方案1】:

    我意识到我可以使用EvtSubscribe。以下代码是我一直在寻找的答案:

    #include <windows.h>
    #include <conio.h>
    #include <stdio.h>
    #include <winevt.h>
    
    #pragma comment(lib, "wevtapi.lib")
    
    #define ARRAY_SIZE 10
    
    DWORD EnumerateResults(EVT_HANDLE hResults);
    DWORD PrintEvent(EVT_HANDLE hEvent);
    BOOL IsKeyEvent(HANDLE hStdIn);
    
    #define QUERY_INTERNET2 L"<QueryList>"\
                L"  <Query Id=\"0\" Path=\"System\">"\
                L"    <Select Path=\"Microsoft-Windows-UniversalTelemetryClient/Operational\">"\
                L" *[System[(EventID=55)]] and *[EventData[Data[@Name='State'] and (Data='true')]]"\
                L"</Select>"\
                L"  </Query>"\
                L"</QueryList>"
    
    void __cdecl wmain()
    {
        DWORD status = ERROR_SUCCESS;
        EVT_HANDLE hSubscription = NULL;
        HANDLE aWaitHandles[2];
        DWORD dwWait = 0;
    
        // Get a handle for console input, so you can break out of the loop.
        aWaitHandles[0] = GetStdHandle(STD_INPUT_HANDLE);
        if (INVALID_HANDLE_VALUE == aWaitHandles[0])
        {
            wprintf(L"GetStdHandle failed with %lu.\n", GetLastError());
            goto cleanup;
        }
    
        // Get a handle to a manual reset event object that the subscription will signal
        // when events become available that match your query criteria.
        aWaitHandles[1] = CreateEvent(NULL, TRUE, TRUE, NULL);
        if (NULL == aWaitHandles[1])
        {
            wprintf(L"CreateEvent failed with %lu.\n", GetLastError());
            goto cleanup;
        }
    
        // Subscribe to events.
        hSubscription = EvtSubscribe(NULL, aWaitHandles[1], NULL, QUERY_INTERNET2, NULL, NULL, NULL, EvtSubscribeStartAtOldestRecord);
        if (NULL == hSubscription)
        {
            status = GetLastError();
    
            if (ERROR_EVT_CHANNEL_NOT_FOUND == status)
                wprintf(L"Channel was not found.\n");
            else if (ERROR_EVT_INVALID_QUERY == status)
                wprintf(L"The query was not found.\n");
            else
                wprintf(L"EvtSubscribe failed with %lu.\n", status);
    
            goto cleanup;
        }
    
        wprintf(L"Press any key to quit.\n");
    
        // Loop until the user presses a key or there is an error.
        while (1)
        {
            dwWait = WaitForMultipleObjects(sizeof(aWaitHandles) / sizeof(HANDLE), aWaitHandles, FALSE, INFINITE);
    
            if (0 == dwWait - WAIT_OBJECT_0)  // Console input
            {
                if (IsKeyEvent(aWaitHandles[0]))
                    break;
            }
            else if (1 == dwWait - WAIT_OBJECT_0) // Query results
            {
                if (ERROR_NO_MORE_ITEMS != (status = EnumerateResults(hSubscription)))
                {
                    break;
                }
    
                ResetEvent(aWaitHandles[1]);
            }
            else
            {
                if (WAIT_FAILED == dwWait)
                {
                    wprintf(L"WaitForSingleObject failed with %lu\n", GetLastError());
                }
                break;
            }
        }
    
    cleanup:
    
        if (hSubscription)
            EvtClose(hSubscription);
    
        if (aWaitHandles[0])
            CloseHandle(aWaitHandles[0]);
    
        if (aWaitHandles[1])
            CloseHandle(aWaitHandles[1]);
    }
    
    // Enumerate the events in the result set.
    DWORD EnumerateResults(EVT_HANDLE hResults)
    {
        DWORD status = ERROR_SUCCESS;
        EVT_HANDLE hEvents[ARRAY_SIZE];
        DWORD dwReturned = 0;
    
        while (1)
        {
            // Get a block of events from the result set.
            if (!EvtNext(hResults, ARRAY_SIZE, hEvents, INFINITE, 0, &dwReturned))
            {
                if (ERROR_NO_MORE_ITEMS != (status = GetLastError()))
                {
                    wprintf(L"EvtNext failed with %lu\n", status);
                }
    
                goto cleanup;
            }
    
            // For each event, call the PrintEvent function which renders the
            // event for display.
            for (DWORD i = 0; i < dwReturned; i++)
            {
                if (ERROR_SUCCESS == (status = PrintEvent(hEvents[i])))
                {
                    EvtClose(hEvents[i]);
                    hEvents[i] = NULL;
                }
                else
                {
                    goto cleanup;
                }
            }
        }
    
    cleanup:
    
        // Closes any events in case an error occurred above.
        for (DWORD i = 0; i < dwReturned; i++)
        {
            if (NULL != hEvents[i])
                EvtClose(hEvents[i]);
        }
    
        return status;
    }
    
    // Render the event as an XML string and print it.
    DWORD PrintEvent(EVT_HANDLE hEvent)
    {
        DWORD status = ERROR_SUCCESS;
        DWORD dwBufferSize = 0;
        DWORD dwBufferUsed = 0;
        DWORD dwPropertyCount = 0;
        LPWSTR pRenderedContent = NULL;
    
        // The EvtRenderEventXml flag tells EvtRender to render the event as an XML string.
        if (!EvtRender(NULL, hEvent, EvtRenderEventXml, dwBufferSize, pRenderedContent, &dwBufferUsed, &dwPropertyCount))
        {
            if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError()))
            {
                dwBufferSize = dwBufferUsed;
                pRenderedContent = (LPWSTR)malloc(dwBufferSize);
                if (pRenderedContent)
                {
                    EvtRender(NULL, hEvent, EvtRenderEventXml, dwBufferSize, pRenderedContent, &dwBufferUsed, &dwPropertyCount);
                }
                else
                {
                    wprintf(L"malloc failed\n");
                    status = ERROR_OUTOFMEMORY;
                    goto cleanup;
                }
            }
    
            if (ERROR_SUCCESS != (status = GetLastError()))
            {
                wprintf(L"EvtRender failed with %d\n", GetLastError());
                goto cleanup;
            }
        }
    
        wprintf(L"\n\n%s", pRenderedContent);
    
    cleanup:
    
        if (pRenderedContent)
            free(pRenderedContent);
    
        return status;
    }
    
    // Determines whether the console input was a key event.
    BOOL IsKeyEvent(HANDLE hStdIn)
    {
        INPUT_RECORD Record[128];
        DWORD dwRecordsRead = 0;
        BOOL fKeyPress = FALSE;
    
        if (ReadConsoleInput(hStdIn, Record, 128, &dwRecordsRead))
        {
            for (DWORD i = 0; i < dwRecordsRead; i++)
            {
                if (KEY_EVENT == Record[i].EventType)
                {
                    fKeyPress = TRUE;
                    break;
                }
            }
        }
    
        return fKeyPress;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-23
      • 2013-11-15
      • 1970-01-01
      相关资源
      最近更新 更多