GetProcessTimes 返回的 CreateTime 是 Windows FILETIME 格式(100纳秒精度,自1601-01-01 UTC起),需用 FileTimeToSystemTime 转换为可读时间;其值精确记录内核创建时刻,不受系统时间调整影响,但实际分辨率受限于系统时钟精度(通常10–15ms)。

GetProcessTimes 返回的 CreateTime 是进程启动时间,但需注意时钟基准
GetProcessTimes 确实能拿到进程创建时间,但它返回的是 Windows FILETIME(100纳秒精度,自 1601-01-01 UTC 起),不是 Unix 时间戳或本地时间。直接打印 CreateTime 的低/高 DWORD 会得到一串无意义数字。
常见错误是把 CreateTime 当作毫秒时间戳用,或者误以为它和 GetSystemTimeAsFileTime 返回值可直接相减比较——其实可以,但必须用 FileTimeToSystemTime 或 FileTimeToLocalFileTime 转换后才便于人类阅读。
- 必须先调用
OpenProcess获取当前进程句柄(GetCurrentProcess()更安全,权限足够) -
CreateTime是内核记录的精确创建时刻,不受系统时间调整影响(如手动改系统时间、NTP 同步) - 多线程环境下,该时间点对应的是
CreateProcess返回前的内核调度时刻,比main函数第一行执行早几微秒到毫秒不等
用 FileTimeToSystemTime 把 CreateTime 转成可读时间
FILETIME 不是结构体,不能直接访问年月日字段;必须经转换才能输出。别用 CTime 或 std::chrono::file_clock(C++20 前不支持 FILETIME 直接构造)。
正确做法是:声明 SYSTEMTIME st = {},再调用 FileTimeToSystemTime(&ftCreate, &st)。失败时检查 GetLastError(),常见原因是传入了非法 FILETIME(如全零)。
- 转换后
st.wYear到st.wMilliseconds就是标准的年月日时分秒毫秒 - 注意
SYSTEMTIME是本地时区时间,若需 UTC 时间,先用FileTimeToUniversalTime(Windows 10 1809+)或手动减去时区偏移 - 如果只要时间戳用于计算(比如判断进程运行了多久),可跳过转换,直接用
ULARGE_INTEGER对CreateTime和当前GetSystemTimeAsFileTime做差,再除以 10000 得到毫秒
获取当前进程启动时间的最小可行代码片段
#include <windows.h>
#include <iostream>
int main() {
HANDLE hProc = GetCurrentProcess();
FILETIME ftCreate, ftExit, ftKernel, ftUser;
if (GetProcessTimes(hProc, &ftCreate, &ftExit, &ftKernel, &ftUser)) {
SYSTEMTIME st = {};
if (FileTimeToSystemTime(&ftCreate, &st)) {
std::cout <p>这段代码在 VS2019+ / MinGW-w64 下都能编译通过。关键点:<code>GetCurrentProcess()</code> 不需要额外权限,比 <code>OpenProcess(PROCESS_QUERY_INFORMATION, ...)</code> 更简洁可靠;<code>ftExit</code> 对当前进程永远为 0(除非已退出),不用处理。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2823" title="C++14"><img
src="https://img.php.cn/upload/manual/001/431/639/6ac8b33c327c4749.png" alt="C++14" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="overflowclass">C++14</a>
<p class="overflowclass">C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<ul>
<li>链接时不需要额外库,<code>kernel32.lib</code> 默认已链入</li>
<li>如果程序被调试器启动(如 VS F5),<code>CreateTime</code> 仍是目标进程自身的创建时间,不是调试器启动时间</li>
<li>沙盒环境(如 Windows AppContainer)可能拒绝返回 <code>GetProcessTimes</code>,此时 <code>GetLastError()</code> 返回 <code>ERROR_ACCESS_DENIED</code>
</li>
</ul>
<h3>替代方案:读取 <code>\Process\ID\StartTime</code> 性能计数器?不推荐</h3>
<p>有人尝试用 <code>PdhOpenQuery</code> + <code>PdhAddCounter</code> 查询 <code>\Process(*)\Start Time</code>,这条路理论上可行,但实际踩坑多:</p>
<ul>
<li>性能计数器名称依赖系统语言(英文系统是 <code>Start Time</code>,中文可能是 <code>启动时间</code>)</li>
<li>必须提前初始化 PDH(<code>PdhOpenQuery</code>),且每轮查询要调用 <code>PdhCollectQueryData</code> + <code>PdhGetFormattedCounterValue</code>,延迟高、开销大</li>
<li>对当前进程 ID 的计数器可能尚未注册(尤其刚启动时),首次调用常返回 <code>PDH_INVALID_DATA</code>
</li>
<li>
<code>GetProcessTimes</code> 是内核原生接口,零额外依赖、无语言适配问题、毫秒级响应</li>
</ul>
<p>除非你在写一个跨平台监控工具并已封装好 PDH 层,否则没必要绕远路。Windows 下查自己进程启动时间,<code>GetProcessTimes</code> 就是最直接、最稳定的选择。</p>
<p>真正容易被忽略的是:FILETIME 的 100 纳秒单位和 Windows 系统时钟精度(通常 10–15ms)并不匹配——<code>CreateTime</code> 理论上精确,但实际分辨率受限于系统时钟中断频率。别指望靠它做微秒级启动时序分析。</p></iostream></windows.h>
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










