I'm trying to make an install script. I want to install an .msi file, Python, and then install other things after Python is installed. I already see how to do a command-line install. However, msiexec returns right away, even when the install is still running. How would I detect the completion of an msi install from a batch script?

  • Do you have any control over the msi file at all? Can you break it down modify it and repackage? Commented Oct 12, 2010 at 3:09
  • no it's not my msi file
    – Claudiu
    Commented Oct 13, 2010 at 16:05

4 Answers 4


Don't know how Python handles passing commands off to Windows/DOS, but using a plain batch file and the start /wait command the batch file stops and waits until the MSI is done before moving on to the next step.

For example, to install a main app, followed by a patch only when it's finished, and then a final program once that's finished, drop these lines into a .cmd file:

start /wait msiexec /i O12Conv.msi /qb
start /wait msiexec /p O12Convsp1-en-us.msp /qb
start /wait msiexec /i mpsetupedp.msi
  • +1, When using start watch for the title "bug". Paths containing a space will be interpreted as the title portion of the command line arguments. Use something like: start "" /wait msiexec /i some.msi /qb just to ensure title is set.
    – jscott
    Commented Oct 19, 2010 at 11:35
  • @jscott Hadn't heard of that problem before, but we've always stored our installers on a specific installer share, and all folder names on that share are strictly 8.3 with no spaces, as there've been so many odd quirks with badly written installers in the past that it ended up easier to keep everything simple.
    – GAThrawn
    Commented Oct 19, 2010 at 12:21
  • I tried this, and I don't know what /qb does but it didn't work, the msiexec call took less than 1second; now trying without the /qb flag it seems it's hanging...
    – knocte
    Commented Nov 4, 2022 at 2:12

It's tricky, and not reliable, but there are ways to monitor for the existence of a specific process in the process list. You write your loop to NOOP while waiting for that process to no longer be there, and then you do your next steps. There are a couple of ways of handling this.

The SysInternals tool pslist will show processes, though parsing the output can be tricky. PowerShell can access the .NET APIs to do process monitoring through the get-process cmdlet.

These methods merely monitor for the existence of a process, they can't check for the exit codes and therefore can't know whether or not a process exited normally or in an error state. For that, you'll have to process any MSI logs you specified be generated, or possibly dig in the Windows Even Log for error events.


In PowerShell, either pipe the result of the direct invocation to somewhere:

msiexec /i my.msi /qn | Out-Null

Or use Start-Process with the -Wait parameter:

Start-Process msiexec -ArgumentList "/i my.msi /qn" -Wait

A successful install will return any of the 3 codes: 0,1641,3010 depending on the reboot option. Please try to modify your script such that it will in return throw the codes.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .