2

I have a Windows desktop application build in C# which auto updates itself when an update is available. It uses an MSI installer package for this.

Sometimes while updating app, a PC shutdown due to power loss can happen, and when system reboots my application gets corrupted. The only option then left is to repair it manually. Is there anything one can do to recover from it automatically?

The update process is started by another exe which is included in package and which has the required administrative rights, using code like this:

Process process = new Process();
process.StartInfo.FileName = "msiexec.exe";
process.StartInfo.Arguments = string.Format(" /qb /i \"{0}\" 
                    ALLUSERS=1 REINSTALLMODE=aums", sMSIPath);
process.Start();
process.WaitForExit();
Doc Brown
  • 199,015
  • 33
  • 367
  • 565
tabby
  • 129
  • 4
  • see my updated question @DocBrown – tabby Mar 23 '18 at 07:25
  • Yes it has administrative rights using app.manifest – tabby Mar 23 '18 at 07:49
  • Commands are executed by another exe which I include into package while building and also there’s no antivirus issue as well – tabby Mar 23 '18 at 07:52
  • I tool the freedom and revised your question. Please proofread and instead of burying additional information here in some comments, use the edit button if you like to improve something. – Doc Brown Mar 23 '18 at 08:44

2 Answers2

4

You can't. The way such things are handled on program start is this:

  1. If not exists updating.file
    • Backup important files into temporary subfolder
    • Create updating.file
    • Continue normally with update
    • Delete temporary subfolder
    • Delete updating.file
    • Launch updated program normally
  2. If exists updating.file
    • Restore application from temporary subfolder
    • Send error report
    • Start program normally (or if you're really bold, attempt update again)

The point is that throughout the update, should it not finish correctly, you are to restore the program to what it was before the update. Understandably, you cannot expect your program to do this, as it is being updated. You must use a second program which does precisely this (and does it well).

Edit: After your update, it would seem to suggest that the problem lies in the fact that you're using the same application to perform the update. The executable itself must be updated, and you cannot guarantee to be able to restore the previous version if the file itself is in use. You must create a program dedicated towards updating the program and only that. Ideally the program would be both flexible and simple in design, so that you don't need to update the updater.

Neil
  • 22,670
  • 45
  • 76
1

The windows installer database actually has a bunch of transactional facilities built into it that can make this pretty nicely handled automatically.

What you're going to want to do however, is execute the msiexec.exe not as a child process, and then exit your process while it's running. Let the installer have a last step of "launch the app" so when it's finished it'll reopen the new application, and it'll be pretty seamless then.

If your app is being updated and open and a reboot happens, the transactional rollbacks may have minor issue with files being in a funny state because they were in use when the MSI attempted to do it's update. If your MSI is well constructed though, while it's being installed, a reboot (even unprompted) will result in either a full rollback or a transaction continuation beginning when the restart completes.

I suspect you do not have your msi setup to execute the file updates in the deferred mode correctly

Per wikipedia (emphasis mine)

[...] Deferred mode. In this phase, the script built in immediate mode is executed in the context of the privileged Windows Installer service. The script must be executed by a privileged account because of the heterogeneity of the scenarios in which a setup operation is initiated. For example, elevated privileges are necessary to serve on-demand installation requests from non-privileged users. (To run with elevated privileges, however, the package must be deployed by a local administrator or advertised by a system administrator using Group Policy.)

Rollback

All installation operations are transactional.[7] In other words, for each operation that Windows Installer performs, it generates an equivalent undo operation that would revert the change made to the system. In case any script action fails during deferred execution, or the operation is cancelled by the user, all the actions performed until that point are rolled back, restoring the system to its original state. Standard Windows Installer actions automatically write information into a rollback script; package authors who create custom actions that change the target system should also create corresponding rollback actions (as well as uninstall actions and uninstallation-rollback actions). As a design feature, if applied correctly this mechanism will also roll back a failed uninstall of an application to a good working state. [...]

Jimmy Hoffa
  • 16,039
  • 3
  • 69
  • 80