【问题标题】:How to track the accurate windows startup time using C++(win32/MFC)如何使用 C++(win32/MFC) 跟踪准确的 Windows 启动时间
【发布时间】:2020-06-24 15:17:39
【问题描述】:

我正在创建一个跟踪系统启动时间的应用程序。 我尝试了 GetTickcount() 方法和 WMI 查询。在这两种情况下,我得到了相同的解决方案。
但我得到的时间与实际启动时间不同。 通过研究,我发现由于在电源选项中启用了快速启动选项,当我们关闭它时系统不会启动。 我需要的是 time 实际启动时间。我们如何使用 C++ 获得实际启动时间?

我在 20 年 6 月 24 日上午 8:22:05 关闭系统并打开它,但我得到的启动时间是 20 年 6 月 22 日下午 5:11:05

【问题讨论】:

    标签: c++ datetime winapi mfc boot


    【解决方案1】:

    启用快速启动选项后,单击开始菜单 -> 关机将使机器进入睡眠模式/休眠状态,而不是关机。但重启菜单不受影响。 (并且在我的测试中,从命令行关闭也不会受到影响)。因此,启动时间不会被重置。

    您可以尝试以下方法:

    1. 关闭“快速启动”选项。
    2. 将任务添加到任务计划以记录系统启动的时间。
    3. 阅读 Windows 事件日志:

    事件 ID 27 记录内核启动事件。正如您在图片中看到的,启动类型0x1 表示它是一个快速启动。您可以只阅读最新的并获得创建时间。

    示例(参考此示例文档:Querying for Events):

    #include <windows.h>
    #include <sddl.h>
    #include <stdio.h>
    #include <winevt.h>
    
    #pragma comment(lib, "wevtapi.lib")
    
    #define ARRAY_SIZE 1
    #define TIMEOUT 1000  // 1 second; Set and use in place of INFINITE in EvtNext call
    
    DWORD PrintResults(EVT_HANDLE hResults);
    DWORD PrintEvent(EVT_HANDLE hEvent); // Shown in the Rendering Events topic
    
    void main(void)
    {
        DWORD status = ERROR_SUCCESS;
        EVT_HANDLE hResults = NULL;
        LPCWSTR pwsPath = L"System";
        LPCWSTR pwsQuery = L"Event/System[EventID=27]";
    
        hResults = EvtQuery(NULL, pwsPath, pwsQuery, EvtQueryChannelPath | EvtQueryReverseDirection);
        if (NULL == hResults)
        {
            status = GetLastError();
    
            if (ERROR_EVT_CHANNEL_NOT_FOUND == status)
                wprintf(L"The channel was not found.\n");
            else if (ERROR_EVT_INVALID_QUERY == status)
                // You can call the EvtGetExtendedStatus function to try to get 
                // additional information as to what is wrong with the query.
                wprintf(L"The query is not valid.\n");
            else
                wprintf(L"EvtQuery failed with %lu.\n", status);
    
            goto cleanup;
        }
    
        PrintResults(hResults);
    
    cleanup:
    
        if (hResults)
            EvtClose(hResults);
    
    }
    // Enumerate all the events in the result set. 
    DWORD PrintResults(EVT_HANDLE hResults)
    {
        DWORD status = ERROR_SUCCESS;
        EVT_HANDLE hEvents[ARRAY_SIZE];
        DWORD dwReturned = 0;
    
        // 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. PrintEvent is shown in RenderingEvents.
        /*for (DWORD i = 0; i < dwReturned; i++)
        {
            if (ERROR_SUCCESS == (status = PrintEvent(hEvents[i])))
            {
                EvtClose(hEvents[i]);
                hEvents[i] = NULL;
            }
            else
            {
                goto cleanup;
            }
        }*/
        if (ERROR_SUCCESS == (status = PrintEvent(hEvents[0])))
        {
            EvtClose(hEvents[0]);
            hEvents[0] = NULL;
        }
        else
        {
            goto cleanup;
        }
    
    
    cleanup:
    
        for (DWORD i = 0; i < dwReturned; i++)
        {
            if (NULL != hEvents[i])
                EvtClose(hEvents[i]);
        }
    
        return status;
    }
    DWORD PrintEvent(EVT_HANDLE hEvent)
    {
        DWORD status = ERROR_SUCCESS;
        DWORD dwBufferSize = 0;
        DWORD dwBufferUsed = 0;
        DWORD dwPropertyCount = 0;
        LPWSTR pRenderedContent = NULL;
    
        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", status);
                goto cleanup;
            }
        }
    
        wprintf(L"%s\n\n", pRenderedContent);
    
    cleanup:
    
        if (pRenderedContent)
            free(pRenderedContent);
    
        return status;
    }
    

    结果:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-17
      • 1970-01-01
      • 2015-10-29
      • 2021-02-12
      • 1970-01-01
      • 2016-08-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多