Search code examples
pythonpython-3.xwindowssubprocessbackground-process

How to start another program and keep it running after Python script finishes?


My issue is similar to How to run Python's subprocess and leave it in background , however none of answers listed there worked for me.

I try to run a program, for example Slack or Discord (or other programs listed in question updates). I want program to run even if my script finishes.

I need this to work on Windows.

Note: the issue happen only when Slack / Discord is started from Python script, if it was running before, then it isn't closed.

Example code: (as you can see I tried multiple ways):

import os, subprocess
from time import sleep
from subprocess import Popen, PIPE, STDOUT

# discord_path=r"C:\Program Files\Discord\Discord.exe"
# discord_path2=r"C:\Users\user\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Discord Inc\Discord.lnk"
# os.startfile(discord_path2)

# subprocess.run([r"C:\Users\user\AppData\Local\Discord\Update.exe", "--processStart", "Discord.exe"],shell=True)
# subprocess.Popen([r"C:\Users\user\AppData\Local\Discord\Update.exe", "--processStart", "Discord.exe"],shell=True)
# subprocess.call([r"C:\Users\user\AppData\Local\Discord\Update.exe", "--processStart", "Discord.exe"])
# subprocess.Popen([r"C:\Users\user\AppData\Local\Discord\Update.exe", "--processStart", "Discord.exe"], stdin=None, stdout=None, stderr=None, close_fds=True)

# slack_path2=r"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Slack Technologies Inc\Slack.lnk"
# os.startfile(slack_path2)
#  stdin=None, stdout=None, stderr=None, 

# subprocess.Popen([r"C:\Program Files\Slack\slack.exe", "--startup"], close_fds=True)

proc = Popen([r"C:\Program Files\Slack\slack.exe", "--startup"], stdout=PIPE, stderr=STDOUT)

sleep(5)
# now program (Slack / Discord) is exited and I can't prevent it

Update: I tested also notepad.exe, calc.exe and winver.

notepad.exe and winver behave the same as Slack and Discord. However calc.exe stays opened after script finishes (so this program is behaves exceptional).

Code:

subprocess.Popen(['notepad.exe'])
subprocess.Popen(['calc.exe'])
subprocess.Popen(['winver'])

Update 2: I need to run a few programs this way (including both Slack and Discord), so using os.execl() won't do the job, because it quits python script immediately.

Update 3: As I put in one of comments, it turned out that I was running python from within vscode, and vscode was somehow closing processes after main Python script finished. When I run Python script from Powershell then most answers below work as desired.


Solution

  • The solution is actually easier then it seemed :]
    We can just use os.popen to run command in cmd/pipe, this will make those processes not dependent on the python process! So let's just do it:

    import os
    
    os.popen("notepad.exe")
    os.popen("notepad.exe")
    
    print("Bye! Now it's your responsibility to close new process(es) :0")
    

    this served as my inspiration, tho this solution works a little differently


    Windows-only:

    Also if you don't want to run several Popen's (through os.popen) to open one cmd.exe and use it instead:

    import subprocess
    from time import sleep
    
    path = r"C:\Windows\System32\cmd.exe"
    p = subprocess.Popen(
        [path],
        bufsize=-1,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        stdin=subprocess.PIPE)
    
    
    def comunicate(process, message):
        process.stdin.write(message)
        process.stdin.flush()
    
    
    comunicate(p, b'notepad.exe\n')
    comunicate(p, b'notepad.exe\n')
    
    sleep(0.1)
    comunicate(p, b'exit\n')  # closes cmd
    
    print("Bye! Now it's your responsibility to close new process :0")