从 NSIS 脚本检测上次系统重启
Detecting last system restart from NSIS script
好吧,正如标题所暗示的那样,这就是检查上次系统重启时间并据此执行一些任务。
我的情况是,在安装过程中,我会要求用户在某些情况下重新启动系统。现在单击 'OK' 安装程序将关闭,用户必须手动重新启动系统。
现在说,用户 运行 安装程序无需再次重新启动系统。现在安装程序应该报告错误并要求重新启动。
到目前为止想到了可能的解决方法。
- 检查并存储系统时间并比较两者。如果用户 运行 在系统重启很长时间后安装程序,此方法将失败。
- 在注册表 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 不支持可变密钥。
好吧,正如标题所暗示的那样,这就是检查上次系统重启时间并据此执行一些任务。
我的情况是,在安装过程中,我会要求用户在某些情况下重新启动系统。现在单击 'OK' 安装程序将关闭,用户必须手动重新启动系统。
现在说,用户 运行 安装程序无需再次重新启动系统。现在安装程序应该报告错误并要求重新启动。
到目前为止想到了可能的解决方法。
- 检查并存储系统时间并比较两者。如果用户 运行 在系统重启很长时间后安装程序,此方法将失败。
- 在注册表 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 不支持可变密钥。