Search code examples
windowswindows-servicesinstallationnsissilent-installer

Disable windows restart/shutdown during software install


I'm developing an auto-updater tool. The architecture is the following: I have a GUI application and a service that communicate between them; the gui application is installed to be run at each os startup and the same is done for the service.

When the GUI application finds that a new update is available it downloads the update and ask to the service to run it in silent mode(I used a service for this task because the installer needs to be run with admin privileges without user interaction). At this point the installer runs (keep in mind that is a child of the service, so it inherits the service run context) in silent mode (as installer system I'm using nsis) and performs a uninstall of the current application (it removes the GUI app and its binaries, stops the service/kills the service and so basically it kills its father, uninstall the service from the system and remove its binaries) and installs the new software package which includes the new gui app and the new service. I'm wondering if during this uninstall/install process is possible to avoid the system to shut down (since a shutdown during this process could corrupt the application files and the application state).

I've read about WM_QUERYENDSESSION and ShutdownBlockReasonCreate but since my installer runs as child of the service it runs in session 0 so as stated here https://devblogs.microsoft.com/oldnewthing/20151002-00/?p=91461 I can't use them. I also can't use SERVICE_ACCEPT_PRE­SHUTDOWN flag because the installer updates the service (so the flag will have no effect after the service removal).

Could you suggest a solution to the problem above? I'm also open to revisit my software architecture if there are no options with the current architecture.

Thanks


Solution

  • I can think of 3 different possible solutions:

    • Use a signed MSI installer and UAC patching. The initial install needs to be elevated but signed patches can be installed by non-admins.

    • Use versioned services; install it in a subfolder named based on the version. The old service would have to run the new service as a normal process and the normal process stops the old service, updates the service binary path and then starts the service as the first steps of the update process. This should allow you to use SERVICE_ACCEPT_PRE­SHUTDOWN.

    • Use the service to start a helper process on the interactive desktop session with WTSQueryUserToken + CreateProcessAsUser. This process should be able to block shutdown.