在软件安装期间禁用 windows restart/shutdown

Disable windows restart/shutdown during software install

我正在开发一个自动更新工具。架构如下: 我有一个 GUI 应用程序和一个在它们之间进行通信的服务; gui 应用程序在每次 os 启动时安装为 运行,并且对服务执行相同的操作。

当 GUI 应用程序发现有可用的新更新时,它会下载更新并以静默模式向 运行 请求服务(我为此任务使用了一项服务,因为安装程序需要 运行 具有管理员权限,无需用户交互)。此时,安装程​​序 运行s(请记住它是服务的子项,因此它继承了服务 运行 上下文)以静默模式(作为安装程序系统,我正在使用 nsis)并执行卸载当前应用程序(它删除 GUI 应用程序及其二进制文件,停止 service/kills 服务,所以基本上它杀死了它的父亲,从系统中卸载服务并删除它的二进制文件)并安装新软件包其中包括新的图形用户界面应用程序和新服务。 我想知道在此 uninstall/install 过程中是否 pos 可以避免系统关闭(因为在此过程中关闭可能会损坏应用程序文件和应用程序状态)。

我读过 WM_QUERYENDSESSION 和 ShutdownBlockReasonCreate 但由于我的安装程序 运行 作为服务的子项,它 运行 在会话 0 中如此处所述 https://devblogs.microsoft.com/oldnewthing/20151002-00/?p=91461 我不能使用它们。我也不能使用 SERVICE_ACCEPT_PRESHUTDOWN 标志,因为安装程序会更新服务(因此该标志在服务删除后将无效)。

你能提出解决上述问题的方法吗?如果当前架构没有选项,我也愿意重新审视我的软件架构。

谢谢

我可以想到 3 种不同的可能解决方案:

  • 使用签名的 MSI 安装程序和 UAC patching。初始安装需要提升,但非管理员可以安装签名补丁。

  • 使用版本服务;将其安装在基于版本命名的子文件夹中。旧服务必须 运行 新服务作为正常进程,正常进程停止旧服务,更新服务二进制路径,然后启动服务作为更新过程的第一步。这应该允许您使用 SERVICE_ACCEPT_PRE­SHUTDOWN

  • 使用该服务在 WTSQueryUserToken + CreateProcessAsUser 的交互式桌面会话上启动辅助进程。这个进程应该可以阻止shutdown。