Python – subprocess.Popen error


I am running an msi installer in silent mode and caching logs in the specific file. The following is the command i need to execute.

C:\Program Files\ My Installer\Setup.exe /s /v "/qn /lv %TEMP%\log_silent.log"

I used:

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s /v "/qn /lv %TEMP%\log_silent.log"'],stdout=subprocess.PIPE).communicate()[0]

to execute the command however it does not recognise the operation and gives error regarding wrong option selected. I have cross-verified and found that the command only works this way.

Best Solution

The problem is very subtle.

You're executing the program directly. It gets:

argv[0] = "C:\Program Files\ My Installer\Setup.exe"
argv[1] = /s /v "/qn /lv %TEMP%\log_silent.log"

Whereas it should be:

argv[1] = "/s"
argv[2] = "/v"
argv[3] = "/qn"
argv[4] = "/lv %TEMP%\log_silent.log"

In other words, it should receive 5 arguments, not 2 arguments.

Also, %TEMP% is directly unknown to the program!

There are 2 ways to fix this problem:

  1. Calling the shell.

    p = subprocess.Popen('C:\Program Files\ My Installer\Setup.exe /s /v "/qn /lv %TEMP%\log_silent.log"', shell=True)
    output = p.communicate()[0]
  2. Directly call program (more safer)

    s = ['C:\Program Files\ My Installer\Setup.exe', '/s /v "/qn /lv %TEMP%\log_silent.log"']
    safes = [os.path.expandvars(p) for p in argument_string]
    p = subprocess.Popen(safes[0], safes[1:])
    output = p.communicate()[0]