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

Windows10中调用SetSystemTime()设置系统时间失败(错误1314)

解决Windows 10下GPS同步系统时间失败(错误码1314)

问题背景

开发程序通过GPS时间同步Windows系统时间,已将GPS时间转换为SYSTEMTIME结构体,但调用SetSystemTime失败,返回错误码1314(客户端缺少所需特权),手动修改系统时间后问题依旧。

代码中的核心问题

  • 未获取进程令牌:HANDLE hToken未初始化,也未调用OpenProcessToken获取当前进程的访问令牌,导致AdjustTokenPrivileges无法正确启用修改系统时间的特权。
  • 临时对象地址无效:&convertDateTimeToSystemTime(gpsTime)取的是函数返回的临时对象地址,临时对象在语句执行后立即销毁,导致SetSystemTime传入无效指针。
  • 特权调整判断错误:仅用GetLastError() == NO_ERROR判断AdjustTokenPrivileges是否成功,忽略了特权已启用时返回的ERROR_NOT_ALL_ASSIGNED(此情况属于操作成功)。

修复后的代码

特权配置与时间设置逻辑

// 打开当前进程的访问令牌
HANDLE hToken;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
    std::stringstream logStream;
    logStream << "Failed to open process token, error code: " << GetLastError();
    std::cout << logStream.str() << std::endl;
    return;
}

// 配置SE_SYSTEMTIME_NAME特权
TOKEN_PRIVILEGES tkp;
LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

BOOL privSuccess = AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
DWORD privErr = GetLastError();

// 特权调整成功的判断:函数返回非0,且错误为NO_ERROR或ERROR_NOT_ALL_ASSIGNED(特权已启用)
if (privSuccess && (privErr == NO_ERROR || privErr == ERROR_NOT_ALL_ASSIGNED))
{
    // 先获取转换后的SYSTEMTIME对象,避免临时对象地址失效
    SYSTEMTIME sysTime = convertDateTimeToSystemTime(gpsTime);
    
    // 注意:SetSystemTime要求传入UTC时间,确认GPS时间是否为UTC格式
    if (SetSystemTime(&sysTime))
    {
        std::stringstream logStream;
        logStream << "Successfully updated system time to: " << timeString;
        std::cout << logStream.str() << std::endl;
    }
    else
    {
        std::stringstream logStream;
        logStream << "Failed to update system time, error code: " << GetLastError();
        std::cout << logStream.str() << std::endl;
    }
}
else
{
    std::stringstream logStream;
    logStream << "Failed to adjust token privileges, error code: " << privErr;
    std::cout << logStream.str() << std::endl;
}

// 关闭令牌句柄,释放资源
CloseHandle(hToken);

时间转换函数(补充说明)

SYSTEMTIME GpsMessageProcessor::convertDateTimeToSystemTime(const Poco::DateTime time)
{
    SYSTEMTIME convertedTime;
    convertedTime.wYear = time.year();
    convertedTime.wMonth = time.month();
    convertedTime.wDay = time.day();
    convertedTime.wHour = time.hour();
    convertedTime.wMinute = time.minute();
    convertedTime.wSecond = time.second();
    convertedTime.wMilliseconds = time.millisecond();

    // 重要提示:SetSystemTime接收UTC时间,如果GPS输出的是本地时间,必须先转换为UTC
    // 若需要时区转换,可使用SystemTimeToTzSpecificLocalTime或相关API实现

    return convertedTime;
}

额外注意事项

  • 管理员权限:程序必须以管理员身份运行,否则无法获取修改系统时间的权限。
  • UTC时间校验:确保传入SetSystemTime的是UTC时间,否则系统时间会出现偏差。
  • 资源释放:使用完进程令牌后必须调用CloseHandle关闭,避免资源泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 16:20:21