从 NSIS 脚本检测上次系统重启

Detecting last system restart from NSIS script

好吧,正如标题所暗示的那样,这就是检查上次系统重启时间并据此执行一些任务。

我的情况是,在安装过程中,我会要求用户在某些情况下重新启动系统。现在单击 'OK' 安装程序将关闭,用户必须手动重新启动系统。

现在说,用户 运行 安装程序无需再次重新启动系统。现在安装程序应该报告错误并要求重新启动。

到目前为止想到了可能的解决方法。

  1. 检查并存储系统时间并比较两者。如果用户 运行 在系统重启很长时间后安装程序,此方法将失败。
  2. 在注册表 RunOnce 中设置一些无效值(只需要值名称)并在安装程序启动时检查该值。由于 RunOnce 的值被 Windows 自动删除,如果安装程序发现条目在那里,很明显用户没有重新启动系统。

有更好的主意吗?

RunOnce 密钥仅适用于管理员,因此您必须牢记这一点。

您可以查看系统已经运行了多长时间运行:

System::Call 'kernel32::GetTickCount64()l.r0'
StrCmp [=10=] error 0 +2
System::Call 'kernel32::GetTickCount()i.r0'

[=12=] 将包含自上次启动以来的毫秒数。 (GetTickCount64 是 Vista+,较旧的系统将在大约 45 天后回滚到 0)

.onInit中,您从注册表中读取之前的值(如果有的话)并进行比较,如果当前值大于之前的值则系统没有重新启动。

另一种选择是将一个值写入(唯一的)易失性注册表项,这些项仅存在于内存中并且在重新启动时会丢失:

!include WinCore.nsh
!include LogicLib.nsh
!ifndef REG_OPTION_VOLATILE
!define REG_OPTION_VOLATILE 1
!endif
System::Call 'advapi32::RegCreateKeyEx(i ${HKEY_LOCAL_MACHINE}, t "Software\Volatile\{f255ae7a-fd7d-11e4-a322-1697f925ec7b}", i0, i0, i ${REG_OPTION_VOLATILE}, i ${GENERIC_WRITE}, i0, *i.r1, *i)i.r0'
${If} [=11=] = 0
        System::Call 'advapi32::RegCloseKey(ir1)'
        WriteRegDWORD HKLM "Software\Volatile\{f255ae7a-fd7d-11e4-a322-1697f925ec7b}" NoReboot 1
${EndIf}

Windows95/98/ME 不支持可变密钥。