You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中获取Windows系统的启动时间?

获取Windows系统启动时间的C++实现方法

首先澄清:GetTickCount64()返回的是系统启动后经过的毫秒数,并非你的exe程序启动时间。如果要得到具体的系统启动日期时间,有以下几种可靠方法:

方法1:通过当前时间反推启动时间

利用系统运行时长和当前时间计算启动时间,步骤简单且兼容性好:

  1. 获取当前高精度系统时间(FILETIME格式)
  2. 用GetTickCount64()获取系统启动后经过的毫秒数
  3. 将毫秒数转换为FILETIME的最小单位(100纳秒),从当前时间中减去该值得到启动时间

代码示例:

#include <windows.h>
#include <iostream>
#include <iomanip>

void GetSystemBootTime(FILETIME* bootTime) {
    FILETIME currentTime;
    GetSystemTimePreciseAsFileTime(&currentTime); // 获取高精度当前时间

    // 转换FILETIME为ULONGLONG便于计算
    ULONGLONG currentTimeLL = ((ULONGLONG)currentTime.dwHighDateTime << 32) | currentTime.dwLowDateTime;
    ULONGLONG elapsedMs = GetTickCount64();
    // 毫秒转100纳秒单位(1ms = 10000 * 100ns)
    ULONGLONG elapsed100Ns = elapsedMs * 10000;

    // 计算启动时间并写回FILETIME结构
    ULONGLONG bootTimeLL = currentTimeLL - elapsed100Ns;
    bootTime->dwHighDateTime = (DWORD)(bootTimeLL >> 32);
    bootTime->dwLowDateTime = (DWORD)(bootTimeLL & 0xFFFFFFFF);
}

int main() {
    FILETIME bootTime;
    GetSystemBootTime(&bootTime);

    // 转换为UTC时间输出
    SYSTEMTIME st;
    FileTimeToSystemTime(&bootTime, &st);
    std::cout << "系统启动时间(UTC):" 
              << std::setw(4) << st.wYear << "-" 
              << std::setw(2) << std::setfill('0') << st.wMonth << "-" 
              << std::setw(2) << st.wDay << " " 
              << std::setw(2) << st.wHour << ":" 
              << std::setw(2) << st.wMinute << ":" 
              << std::setw(2) << st.wSecond << std::endl;

    // 转换为本地时间输出
    FileTimeToLocalFileTime(&bootTime, &bootTime);
    FileTimeToSystemTime(&bootTime, &st);
    std::cout << "系统启动时间(本地):" 
              << std::setw(4) << st.wYear << "-" 
              << std::setw(2) << std::setfill('0') << st.wMonth << "-" 
              << std::setw(2) << st.wDay << " " 
              << std::setw(2) << st.wHour << ":" 
              << std::setw(2) << st.wMinute << ":" 
              << std::setw(2) << st.wSecond << std::endl;

    return 0;
}

方法2:使用原生API直接查询

通过NtQuerySystemInformation直接获取系统启动时间,效率更高,需要链接ntdll.lib:

#include <windows.h>
#include <winternl.h>
#include <iostream>
#include <iomanip>

#pragma comment(lib, "ntdll.lib")

typedef struct _SYSTEM_BOOT_INFORMATION {
    LARGE_INTEGER BootTime;
} SYSTEM_BOOT_INFORMATION, *PSYSTEM_BOOT_INFORMATION;

int main() {
    SYSTEM_BOOT_INFORMATION bootInfo;
    NTSTATUS status = NtQuerySystemInformation(SystemBootInformation, &bootInfo, sizeof(bootInfo), nullptr);

    if (NT_SUCCESS(status)) {
        FILETIME bootTime;
        bootTime.dwHighDateTime = bootInfo.BootTime.HighPart;
        bootTime.dwLowDateTime = bootInfo.BootTime.LowPart;

        // 转换为本地时间输出
        SYSTEMTIME st;
        FileTimeToLocalFileTime(&bootTime, &bootTime);
        FileTimeToSystemTime(&bootTime, &st);
        std::cout << "系统启动时间(本地):" 
                  << std::setw(4) << st.wYear << "-" 
                  << std::setw(2) << std::setfill('0') << st.wMonth << "-" 
                  << std::setw(2) << st.wDay << " " 
                  << std::setw(2) << st.wHour << ":" 
                  << std::setw(2) << st.wMinute << ":" 
                  << std::setw(2) << st.wSecond << std::endl;
    } else {
        std::cerr << "获取启动时间失败,错误码:" << status << std::endl;
    }

    return 0;
}

方法3:通过WMI查询(适合多系统信息场景)

如果需要同时获取其他系统属性,可以通过WMI查询Win32_OperatingSystem类的LastBootUpTime属性,需要链接wbemuuid.lib:

#include <windows.h>
#include <wbemidl.h>
#include <iostream>
#include <iomanip>

#pragma comment(lib, "wbemuuid.lib")

int main() {
    HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
    if (FAILED(hr)) {
        std::cerr << "COM初始化失败,错误码:" << hr << std::endl;
        return 1;
    }

    hr = CoInitializeSecurity(nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE, nullptr);
    if (FAILED(hr)) {
        std::cerr << "安全初始化失败,错误码:" << hr << std::endl;
        CoUninitialize();
        return 1;
    }

    IWbemLocator* pLoc = nullptr;
    hr = CoCreateInstance(CLSID_WbemLocator, nullptr, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);
    if (FAILED(hr)) {
        std::cerr << "创建WbemLocator失败,错误码:" << hr << std::endl;
        CoUninitialize();
        return 1;
    }

    IWbemServices* pSvc = nullptr;
    hr = pLoc->ConnectServer(L"ROOT\\CIMV2", nullptr, nullptr, nullptr, 0, nullptr, nullptr, &pSvc);
    if (FAILED(hr)) {
        std::cerr << "连接WMI服务失败,错误码:" << hr << std::endl;
        pLoc->Release();
        CoUninitialize();
        return 1;
    }

    hr = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE);
    if (FAILED(hr)) {
        std::cerr << "设置代理失败,错误码:" << hr << std::endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return 1;
    }

    IEnumWbemClassObject* pEnumerator = nullptr;
    hr = pSvc->ExecQuery(L"WQL", L"SELECT LastBootUpTime FROM Win32_OperatingSystem", WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, nullptr, &pEnumerator);
    if (FAILED(hr)) {
        std::cerr << "执行查询失败,错误码:" << hr << std::endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return 1;
    }

    IWbemClassObject* pclsObj = nullptr;
    ULONG uReturn = 0;
    while (pEnumerator) {
        hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
        if (uReturn == 0) break;

        VARIANT vtProp;
        hr = pclsObj->Get(L"LastBootUpTime", 0, &vtProp, nullptr, nullptr);
        if (SUCCEEDED(hr)) {
            // 解析WMI时间格式(YYYYMMDDHHMMSS.ffffff+UUU)
            SYSTEMTIME st;
            if (swscanf_s(vtProp.bstrVal, L"%4hu%2hu%2hu%2hu%2hu%2hu", &st.wYear, &st.wMonth, &st.wDay, &st.wHour, &st.wMinute, &st.wSecond) == 6) {
                st.wMilliseconds = 0;
                std::cout << "系统启动时间(本地):" 
                          << std::setw(4) << st.wYear << "-" 
                          << std::setw(2) << std::setfill('0') << st.wMonth << "-" 
                          << std::setw(2) << st.wDay << " " 
                          << std::setw(2) << st.wHour << ":" 
                          << std::setw(2) << st.wMinute << ":" 
                          << std::setw(2) << st.wSecond << std::endl;
            }
            VariantClear(&vtProp);
        }
        pclsObj->Release();
    }

    pEnumerator->Release();
    pSvc->Release();
    pLoc->Release();
    CoUninitialize();
    return 0;
}

注意事项

  • GetTickCount64()不受系统时间调整影响,适合计算相对时长;若需绝对时间,优先选方法1或2
  • 方法2的原生API效率最高,支持Windows XP及以上系统
  • WMI方法功能全面但开销较大,适合需要批量获取系统信息的场景

内容的提问来源于stack exchange,提问作者vrajeshirke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 16:30:44