简体   繁体   中英

Detect if MSI requires a reboot before installation

If I launch an installer with MSIExec in quiet mode I can detect if a reboot is required to complete installation by checking if the exit code is 3010. But what I'd like to be able to do in a programmable form is test whether or not the installation of an MSI will require a reboot to complete before I launch the actual installer.

I've looked around at the MSI APIs:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa369426(v=vs.85).aspx

I did think I could:

  1. Call MsiOpenPackage to get the installer ready to run
  2. Call MsiDoAction with the following: CostInitialize, FileCost, CostFinalize, InstallValidate
  3. Read records from the FilesInUse table (the following documentation on MSDN suggests this table is created after running CostFinalize/InstallValidate:

http://msdn.microsoft.com/en-us/library/aa369546(VS.85).aspx

However that table doesn't actually appear to exist when I query for it during the installation process. Are there any other ways to check if a reboot will be required?

Gareth, theoretically you don't need to perform the actual install, you should execute just the actions until InstallValidate (included) because then the Files In Use messages appear. However, when the installation is performed with an an external UI handler the Windows Installer may behave a little different so that should be tested.

The decision gets eventually made only during installation itself. As you know, it depends on circumstances like DLLs locked by a concurrently runnning application and therefore it is quite volatile.

There is no way that would guarantee you that you will not receive exit code 3010 after the real installation has completed.

That said, the exit code is not that closely bound to files in use. It may also indicate an inability to stop a service or perhaps some other transient or permanent condition. You can not learn whether a service could be stopped until you try.

Jirka is right about the volatility of is a restart required - all kinds of things could happen during the installation process.

However, I think I've got close to what I'd like to be able to do with a different method:

  1. Register an external UI handler for INSTALLLOGMODE_RMFILESINUSE
  2. Capture INSTALLMESSAGE_RMFILESINUSE messages
  3. If I capture any INSTALLMESSAGE_RMFILESINUSE messages, return -1 and exit installation before any file copying proceeds

In this way I can attempt a silent background installation of software but if for any reason it looks like I won't be able to complete the install I can hold back. I think I might be able to do a rollback using the MsiBeginTransaction and MsiEndTransaction functions as well if I do end up in a state of the user has locked a file after starting to copy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM