2

I am making a virtual assistant that can start several programs using subprocess.Popen("path/to/app.exe"). But when I exit the python program, all of processes are killed. I want the processes (the applications started with Popen) to be independent and remain alive after main process is killed.

I have tried adding start_new_session=True as argument in subprocess.Popen() as some posts have suggested, but it's still not working.

I don't think showing the code is necessary, but still, here you go.

app_path = r'C:\Users\myusername\AppData\Local\Discord\app-1.0.9001\discord.exe'
subprocess.Popen(app_path)  # also tried adding start_new_session=True as argument
Kirk KD
  • 97
  • 9
  • `app_path = r'C:\Users\myusername\AppData\Local\Discord\app-1.0.9001\discord.exe' subprocess.Popen(['start', app_path])` Does this work? (can't easily test; not on windows at the moment). – jrbergen May 18 '21 at 00:08
  • Can't reproduce/test with discord on my computer, but maybe a creation flag can help you, like DETACHED_PROCESS or CREATE_NEW_CONSOLE https://docs.python.org/3/library/subprocess.html#windows-constants – Talon May 18 '21 at 00:13
  • @jrbergen I tried your solution, but it shows `FileNotFoundError: [WinError 2] The system cannot find the file specified`, even though I am 100% sure the file exists. – Kirk KD May 18 '21 at 00:21
  • @Talon Am I supposed to use it like `import subprocess subprocess.DETACHED_PROCESS = True`? If so, it still doesn't work; But I might be using it wrong. – Kirk KD May 18 '21 at 00:21
  • 1
    @KirkKD you pass flags to Popen with `subprocess.Popen(app_path, creationflags=subprocess.DETACHED_PROCESS)`. If you want multiple flags, you join them together with the `|` logic-or operator. – Talon May 18 '21 at 00:24
  • @Talon Thank you, but the child processes still get kill with the python program. – Kirk KD May 18 '21 at 00:26
  • @Kirk KD What happens if you try it with quotes (not sure if it would matter as there are no spaces in the pathname though). Like this: app_path = r'"C:\Users\myusername\AppData\Local\Discord\app-1.0.9001\discord.exe"' subprocess.Popen(['start', app_path]) – jrbergen May 18 '21 at 00:27
  • @jrbergen I did wrap the path in quotes when testing and I tried paths both with and without spaces in them. – Kirk KD May 18 '21 at 00:31

2 Answers2

1

Since you're on Windows, you can call the start command, which exists for this very purpose: to run another program independently of the one that starts it.

The start command is provided by the command-line interpreter cmd.exe. It is not an executable: there is no start.exe. It is a "shell command" (in Linux terminology), which is why shell=True must be passed when creating the subprocess.

You won't be able to communicate with the subprocess started in this way, that is, not via the pipe mechanism provided by the subprocess module. So instead of Popen, you may just use the convenience function run:

from subprocess import run
app = 'notepad'
run(['start', app], shell=True)

The example starts the Notepad editor (instead of Discord in the question) in order to make it easier to reproduce.

In cases where the full path to the app contains spaces, we can either call start like so

app = r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'
run(f'start "" "{app}"', shell=True) 

using the Edge browser in this example, or pass the directory separately:

folder = r'C:\Program Files (x86)\Microsoft\Edge\Application'
app = 'msedge.exe'
run(['start', '/d', folder, app], shell=True)

This is needed because start treats a single argument as the window title if that argument is in quotes. And only if not does it treat it as the command. See "Can I use the start command with spaces in the path?" (on SuperUser) for more details.

john-hen
  • 4,410
  • 2
  • 23
  • 40
0

Answered here: https://stackoverflow.com/a/34718600/4355695

subprocess.Popen(full_command, shell=True, close_fds=True)

(In my linux system I have to put shell=True if I'm passing a full command as string instead of a split-up array of arguments. In windows it may differ, idk)

Nikhil VJ
  • 5,630
  • 7
  • 34
  • 55