我正在尝试通过获取当前时间SYSTEMTIME结构来提取启动时间,然后将其转换为FILETIME,然后转换为ULARGE_INTEGER,我从中减去GetTickCount64(),然后继续将所有内容转换回SYSTEMTIME。
我正在将此功能与“NET STATISTICS WORKSTATION”进行比较,出于某种原因,我的输出已关闭几个小时,这似乎与任何时区差异都不匹配。
这是visual studio示例代码:
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#define KILOBYTE 1024
#define BUFF KILOBYTE
int _tmain(int argc, _TCHAR* argv[])
{
ULARGE_INTEGER ticks, ftime;
SYSTEMTIME current, final;
FILETIME ft, fout;
OSVERSIONINFOEX osvi;
char output[BUFF];
int retval=0;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
ZeroMemory(&final, sizeof(SYSTEMTIME));
GetVersionEx((OSVERSIONINFO *) &osvi);
if (osvi.dwBuildNumber >= 6000) ticks.QuadPart = GetTickCount64();
else ticks.QuadPart = GetTickCount();
//Convert miliseconds to 100-nanosecond time intervals
ticks.QuadPart = ticks.QuadPart * 10000;
//GetLocalTime(¤t); -- //doesn't really fix the problem
GetSystemTime(¤t);
SystemTimeToFileTime(¤t, &ft);
printf("INITIAL: Filetime lowdatetime %u, highdatetime %u\r\n", ft.dwLowDateTime, ft.dwHighDateTime);
ftime.LowPart=ft.dwLowDateTime;
ftime.HighPart=ft.dwHighDateTime;
//subtract boot time interval from current time
ftime.QuadPart = ftime.QuadPart - ticks.QuadPart;
//Convert ULARGE_INT back to FILETIME
fout.dwLowDateTime = ftime.LowPart;
fout.dwHighDateTime = ftime.HighPart;
printf("FINAL: Filetime lowdatetime %u, highdatetime %u\r\n", fout.dwLowDateTime, fout.dwHighDateTime);
//Convert FILETIME back to system time
retval = FileTimeToSystemTime(&fout, &final);
printf("Return value is %d\r\n", retval);
printf("Current time %d-%.2d-%.2d %.2d:%.2d:%.2d\r\n", current.wYear, current.wMonth, current.wDay, current.wHour, current.wMinute, current.wSecond);
printf("Return time %d-%.2d-%.2d %.2d:%.2d:%.2d\r\n", final.wYear, final.wMonth, final.wDay, final.wHour, final.wMinute, final.wSecond);
return 0;
}
答案 0 :(得分:2)
我运行它并发现它在使用GetLocalTime
而不是以UTC表示的GetSystemTime时正常工作。因此,GetSystemTime不一定与PC上的“时钟”匹配是有道理的。
除此之外,问题可能是对GetVersionEx的调用。如上所述,我认为它将始终为所有值返回零。在调用之前你需要这一行:
osvi.dwOSVersionInfoSize = sizeof( osvi );
否则dwBuildNumber将为零,它将调用GetTickCount,这只有49天左右。另一方面,如果是这种情况,我认为你会得到一个有更大差异的结果。
我不完全确定(如所写的)检查是否需要选择要调用的滴答计数功能。如果GetTickCount64不存在,由于缺少入口点,应用程序将无法加载(除非使用了延迟加载......在这种情况下我不确定)。我相信有必要使用LoadLibrary和GetProcAddress在这两个函数之间动态做出决策,并让它在较旧的平台上运行。