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.
CodePudding user response:
You should use os.spawn*()
function to create new process
Here's your example:
We run the program at the path
with the nonblocking flag os.P_NOWAIT
The last two arguments are given to the process. (yeah, if you're not familiar, the first argument should be the path of the program, by which it's called, and then your arguments, for more info google 'argv')
import os
path = r"C:\Program Files\Slack\slack.exe"
os.spawnl(os.P_NOWAIT, # flag
path, # programm
path, "--startup") # arguments
print("Bye! Now it's your responsibility to close new process :0")
CodePudding user response:
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")
CodePudding user response:
As I use neither discord not slack I could not test anything. But I would try to use the process creation flags to break as many links as possible between the new process and the Python program:
from subprocess import Popen, CREATE_NEW_PROCESS_GROUP, DETACHED_PROCESS
proc = Popen([r"C:\Program Files\Slack\slack.exe", "--startup"],
creationflags=CREATE_NEW_PROCESS_GROUP|DETACHED_PROCESS)
CodePudding user response:
you should be able to run the program as a command and not a subprocess. you'll need to excecute a command using the os.system(*your command*)
function. you'll have to import it with import os
That way it should launch the program seperate and not in a subprocess
CodePudding user response:
It turned out that I just needed to run Python script not from vscode, but for example from Powershell.