8

I've built a setup.exe in C# that runs several chained MSI's (with the /QUIET /NORESTART). At the end I'd like to check if a reboot is needed in the machine (that is, if one of the MSI's requested a reboot).

How can I detect so?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Nestor
  • 13,706
  • 11
  • 78
  • 119
  • I've even seen this utility: http://exodusdev.com/products/whyreboot which knows not only that a restart is needed, but also WHY... How do I retrieve such information programmatically? Registry? – Nestor Nov 06 '09 at 06:48
  • See follow up to this question here: http://stackoverflow.com/questions/1689610/how-to-detect-programmatically-when-the-install-updates-and-shut-down-the-comput – Nestor Nov 06 '09 at 20:28

3 Answers3

6

The following registry location has the information:

Key HKLM\System\CurrentControlSet\Control\Session Manager, value PendingFileRenameOperations

Source: http://technet.microsoft.com/en-us/sysinternals/bb897556.aspx

mklement0
  • 382,024
  • 64
  • 607
  • 775
Vinko Vrsalovic
  • 330,807
  • 53
  • 334
  • 373
  • I have a machine without PendingFileRenameOperations showing the little shield in the "Shut down" button. How come? – Nestor Nov 06 '09 at 15:06
  • Doesn't that shield in the shutdown button mean "Install updates and shutdown"? That's not equivalent to a required restart. – Vinko Vrsalovic Nov 06 '09 at 15:17
  • ok... do you know then how to detect taht shield? I put that as a separate question and someone complained that it was a duplicate of this one :-) – Nestor Nov 06 '09 at 16:57
2

Another way to accomplish this is to check the exit codes of all of the MSIs that you run in your code. If an MSI has an exit code of 3010 then it requires a reboot. (http://msdn.microsoft.com/en-us/library/aa368542.aspx).

Assuming that you're using System.Diagnostics.Process to run the MSIs and after the process has exited, you would retrieve the processes exit code using the ExitCode property (http://msdn.microsoft.com/en-us/library/system.diagnostics.process.exitcode(v=vs.90).aspx).

So, you can simply check the exit code of an MSI process and when you're done running all of your MSIs, if any of them returned 3010 then you know you need to reboot.

bsara
  • 7,940
  • 3
  • 29
  • 47
  • 2
    I have learned that some MSIs will not use an exit code of 3010 if the system is already pending a restart when you run the MSI. Microsoft's .NET Framework 4.5.2 offline installer is an example of one such MSI that exhibits this behavior. It simply returns an exit code of 0 if you run it again without having re-booted between executions of the MSI. – afournier Feb 17 '16 at 15:20
  • 1
    @user16563 Thanks for the info, it's good to know. Yet another great example of how confusingly inconsistent Windows tends to function. :) – bsara Feb 17 '16 at 22:33
0

To complement Vinko Vrsalovic's helfpul answer with a PowerShell command:

$rebootPending = $null -ne 
  (Get-ItemProperty 'HKLM:\System\CurrentControlSet\Control\Session Manager').PendingFileRenameOperations

Note that $rebootPending equalling $true indicates that a system reboot is pending for any reason, not just due to MSI-based installations.

mklement0
  • 382,024
  • 64
  • 607
  • 775