Force Reboot from Custom Action in Msi in C#

2019-05-11 10:14发布

How can we prompt for a computer restart after install from within a C# custom action?

We are using VS 2005's setup project for our setup, and we need to programmatically decide to prompt for a restart (so it will not happen on every install, just on some).

UPDATE: We're looking for something that is already built into the MSI custom action system first. If that doesn't exist, we can resort to restarting the PC ourselves somehow, but would like to avoid that.

UPDATE: We see where you can set REBOOT=Force when edited the Msi in Orca, can you modify these tables from a C# custom action at runtime? We could set this to restart every time, but that might make our setup annoying (it will only need to restart on rare occasions).

UPDATE: We tried setting:

savedState["REBOOT"] = "Force";

From within the Install() method of our custom action, but no luck. It doesn't seem like the IDictionary, savedState really does anything.

Also tried:

Context.Parameters["REBOOT"] = "Force";

But I think this collection is just the command line arguments passed to the custom action.

UPDATE: Is there a way to edit our MSI with Orca to make this trick work? Maybe schedule a reboot on a condition of some file existing? We have not found how to set MSI properties from a C# custom action.

UPDATE: We tried hooking into AppDomain.ProcessExit and AppDomain.DomainUnload and starting a new thread and calling Process.GetCurrentProcess().WaitForExit() and none of those events will fire from within a C# custom action...

4条回答
淡お忘
2楼-- · 2019-05-11 11:00

LanceSc has given you the answer. You need to run ScheduleReboot, and the best way to do so is to insert it in the InstallExecuteSequence conditioned by your own custom property that you set inside your custom action.

As you mention, Wix is the way to go for future flexibility. Wix now also includes DTF (Deployment Tools Foundation) which is a rich set of .NET class libraries that wrap the entire Windows API. You can use this to easily access MSI databases from C# or to write C# custom actions. I can provide more info on this if desirable.

查看更多
甜甜的少女心
3楼-- · 2019-05-11 11:02

You need to add or call the MSI custom action ScheduleReboot http://msdn.microsoft.com/en-us/library/aa371527(VS.85).aspx in your InstallExecuteSequence, . You can do this by using the MSI function MsiDoAction, http://msdn.microsoft.com/en-us/library/aa370090(VS.85).aspx inside a custom action. Please note that the custom action that schedules this must be an immediate custom action, not a deferred custom action. This means you will probably need to schedule it after InstallFinalize. You could also add it to the InstallExecuteSequence with a condition on a public property that your custom action sets.

查看更多
地球回转人心会变
4楼-- · 2019-05-11 11:03

When I've had to do this before we used a Win32 API function from user32.dll, I think this was it: ExitWindowsEx()

查看更多
一纸荒年 Trace。
5楼-- · 2019-05-11 11:10

As it seems, the only way for us to solve this is to either:

A) Modify the MSI with orca to make the setup restart for every install

B) Redo the setup project with WiX or Install Shield

Thanks for the help guys.

查看更多
登录 后发表回答