Home > OS >  How to execute code after application closure?
How to execute code after application closure?

Time:12-10

for a self-built installer I need a way to execute code after closing of an application itself.

Application structure

  1. Main application: The installer is started from it when needed, it closes itself in the process.
  2. Installer: This is also located in the folder of the main application and therefore also accesses all dll files. When an update is available, a zip file is first downloaded and then unpacked into the temp folder. Afterwards, all files are moved from there to the shared application directory.

The problem

The problem is that the updater can only update a few dll files at runtime that are not used by itself, because some are write-protected due to the installer's access.

A solution

Moving the files from the temp folder to the shared application folder must happen after closing the installer. But I don't know how to realize that.

Thanks a lot!

CodePudding user response:

Your question implies Windows. I'll make a suggestion from a Win32 perspective.

In our application, we have a similar issue. Periodically, our application downloads an update executable into a temp folder and then launches it. When the update EXE runs, it makes sure the main application has exited, unpacks the files into the application's installation folder, and then starts the application back up again. It's actually more complicated than that, as it really copies the new files into a different install folder, but I'll save those details unless you really need it.

The problem is that the updater can only update a few dll files at runtime that are not used by itself, because some are write-protected due to the installer's access.

This is the core of your issue. My advice is to have the Installer EXE statically linked to both the VC runtime and the other code its sharing with the application. That is, no DLL dependencies all. If you really need to share code between the installer and the application, but still want the application to use a DLL, you can do this. Have the shared code built as both a DLL (with a stub lib) and also built as a full LIB. May require some minor refactoring to your build or redundantly build the same source files. ​The Installer code links with the full LIB. The application code links with the stub LIB for the DLL like it does now.

If you are just looking for a way to launch the process, the API you want is CreateProcess.

Also, have you looked at the open source options like Omaha - which is what Google Chrome has used for silent updates?

CodePudding user response:

Moving the files from the temp folder to the shared application folder must happen after closing the installer. But I don't know how to realize that.

The "Windows way" would be to use PendingFileRenameOperations as described in this blog-post and have Windows do the move during the next startup. Of course that implies one more of the annoying "Please reboot to finish the installation" messages.

CodePudding user response:

If your problem are the DLLs shared by the installer and main application, then you can do this: Before you run the installer, your main application can copy all the needed DLLs and the installer EXE from your main application folder to a temporary folder and run it from there. Your installer must then only wait until the main application gets closed and then replace all its files in the main folder. And once your update is finished, delete this temporary copy of the installer with its DLLs.

Note that if you want to overwrite files in Program Files folder, your installer will have to be run with elevated privileges. Google for "runas" command... you will need it when starting your installer with QProcess.

But there may be also other problems. If your first installation was with normal installer, it typically creates some entries in registry and also generates list of files for later uninstall. And if your new versions will contain different files than originally installed version, then your subsequent uninstall may malfunction or may leave some files existing on users' computers. And you certainly do not want this.

And yet another potential problem. You may have running several instances of your application. In that case quitting one instance will still leave the other instances running and hence their files will not be replacable by the installer - it will fail.

So as you can see, these are quire serious aspects to take into account.

How I do it in my software and I suggest you try it too? I prepare one installer file (.exe) with InnoSetup (freeware!). This can be used for first installation as well as for automatic updates. Then if I create a new version and put it on the server, the running main application detects it, downloads the new installer and runs this installer (of course it asks the user if it should proceed). The installer then asks for elevated privileges, asks to close the running application (it usually is closed automatically when starting the installer) and overwrites the existing installation. All this is standard functionality built in the installer created by InnoSetup. And correctly updates the uninstall instructions... It took me several days to set up everything to my needs but it works well. The only "drawback" is that it is not completely silent, it shows some dialogs. But this is no real issue for me. Maybe it is better for the users to see what is happening on their computer...

  •  Tags:  
  • c qt
  • Related