Python file closes after program execution finishes when using os.startfile() - python

I have a program that produces a csv file and right at the end I am using os.startfile(fileName) but then due to the program finishing execution the opening file just closes also, same happens if I add a sleep after also, file loads up then once the sleep ends it closes again?
Any help would be appreciated.

From the documentation for os.startfile:
startfile() returns as soon as the associated application is launched. There is no option to wait for the application to close, and no way to retrieve the application’s exit status.
When using this function, there is no way to make your script wait for the program to complete because you have no way of knowing when it is complete. Because the program is being launched as a subprocess of your python script, the program will exit when the python script exits.
Since you don't say in your question exactly what the desired behavior is, I'm going to guess that you want the python script to block until the program finishes execution (as opposed to detaching the subprocess). There are multiple ways to do this.
Use the subprocess module
The subprocess module allows you to make a subprocess call that will not return until the subprocess completes. The exact call you make to launch the subprocess depends heavily on your specific situation, but this is a starting point:
subprocess.Popen(['start', fileName], shell=True)
Use input to allow user to close script
You can have your script block until the user tells the python script that the external program has closed. This probably requires the least modification to your code, but I don't think it's a good solution, as it depends on user input.
os.startfile(fileName)
input('Press enter when external program has completed...')

Related

Running a .bat file using subprocess module and passing it input

Quick question on running a batch file using subprocess module in python.
Background
I'm running a .bat file from python and the .bat runs a windows application 100% (takes around a minute) and then waits for input from stdio (x or Esc) to close it.
What I'm doing is:
subprocess.call([r'C:\Users\caSaira\Desktop\myExample.bat'], shell=True)
Since I wasn't sure on how to give x or Esc, I didn't do anything (was under assumption that this will be in waiting stage for input).
But, Looks like the windows application runs in an infinite loop.
Questions
Does anyone know how I can pass 'x' letter, once I complete the execution?
Does anyone know why the application went in infinite loop instead of waiting stage?
I figured it out finally .. I have to use Popen and use the communicate function.
cmd1 = [r'myFile.bat']
p = SP.Popen(cmd1,stdin=SP.PIPE,stdout=SP.PIPE)
output = p.communicate(input='x'.encode())[0]
print(output.decode('ascii'))

Closing a python file inside another python file

I have made a code to open an inputed python file on key command in python pygame_functions
import os, pygame_functions
if spriteclicked(Sprite1):
os.system('file.py')
Similarly how do I close an inputed python file on key command
Your question is not very clear. By 'inputed file' do you mean that the name of the file is from user input? Or that the data in the file is from user input in some way and you want to access it?
I'm going to skip past that part and try to address what I think you are asking about. The line:
os.system('file.py')
tells the OS to run the script file.py. Because you are running it with os.system() your control is limited after you do that. You run the program and do not regain control until that program exits.
If you want to be able to run the command and then stop it when the user types a key, you need to run it in a different way. You would have to run it in a subprocess or a different thread so that you still have an active thread that is not blocked. It can monitor for the user input and then have it do something to shut it down. Exactly how you would shut it down would depend to some degree on the command you ran and how you started it.
Try looking here for some guidance on replacing the os.sytem() call.

Control executed programm with python

I want to execute a testrun via bash, if the test needs too much time. So far, I found some good solutions here. But since the command kill does not work properly (when I use it correctly it says it is not used correctly), I decided to solve this problem using python. This is the Execution call I want to monitor:
EXE="C:/program.exe"
FILE="file.tpt"
HOME_DIR="C:/Home"
"$EXE" -vm-Xmx4096M --run build "$HOME_DIR/test/$FILE" "Auslieferung (ML) Execute"
(The opened *.exe starts a testrun which includes some simulink simulation runs - sometimes there are simulink errors - in this case, the execution time of the tests need too long and I want to restart the entire process).
First, I came up with the idea, calling a shell script containing these lines within a subprocess from python:
import subprocess
import time
process = subprocess.Popen('subprocess.sh', shell = True)
time.sleep(10)
process.terminate()
But when I use this, *.terminate() or *.kill() does not close the program I started with the subprocess call.
That´s why I am now trying to implement the entire call in python language. I got the following so far:
import subprocess
file = "somePath/file.tpt"
p = subprocess.Popen(["C:/program.exe", file])
Now I need to know, how to implement the second call "Auslieferung (ML) Execute" of the bash function. This call starts an intern testrun named "Auslieferung (ML) Execute". Any ideas? Or is it better to choose one of the other ways? Or can I get the "kill" option for bash somewhere, somehow?

Create a Process in Python that Starts After Main Process Ends

I have a python script named "prog.py". I want to add a feature that opens a new process that watches the operation of the current script. When the script terminates, the process recognizes the termination and then invokes a certain function. Here is a pseudo-code:
while (script is active):
sleep(1) # check its status once a second
func()
Do you have any idea how to do it?
Is there a reason the other process needs to be launched first? Seems like you could do this more efficiently and reliably by just execing when the first process completes. For example:
import atexit
import os
atexit.register(os.execlp, 'afterexitscript.py', 'afterexitscript.py', 'arg1', 'arg2')
When the current Python process exits, it will seamlessly replace itself with your other script, which need not go to the trouble of including a polling loop. Or you could just use atexit to execute whatever func is directly in your main script and avoid a new Python launch.

Start another program and leave it running when the script ends

I'm using subprocess.Popen to launch an external program with arguments, but when I've opened it the script is hanging, waiting for the program to finish and if I close the script the program immediately quits.
I thought I was just using a similar process before without issue, so I'm unsure if I've actually done it wrong or I'm misremembering what Popen can do. This is how I'm calling my command:
subprocess.Popen(["rv", rvFile, '-nc'])
raw_input("= Opened file")
The raw_input part is only there so the user has a chance to see the message and know that the file should be opened now. But what I end up getting is all the information that the process itself is spitting back out as if it were called in the command line directly. My understanding was that Popen made it an independent child process that would allow me to close the script and leave the other process open.
The linked duplicate question does have a useful answer for my purposes, though it's still not working as I want it.
This is the answer. And this is how I changed my code:
DETACHED_PROCESS = 0x00000008
pid = subprocess.Popen(["rv", rvFile, '-nc'], creationflags=DETACHED_PROCESS).pid
raw_input("= Opened file")
It works from IDLE but not when I run the py file through the command prompt style interface. It's still tied to that window, printing the output and quitting the program as soon as I've run the script.
The stackoverflow question Calling an external command in python has a lot of useful answers which are related.
Take a look at os.spawnl, it can take a number of mode flags which include NOWAIT, WAIT.
import os
os.spawnl(os.P_NOWAIT, 'some command')
The NOWAIT option will return the process ID of the spawned task.
Sorry for such a short answer but I have not earned enough points to leave comments yet. Anyhow, put the raw_input("= Opened file") inside the file you are actually opening, rather than the program you are opening it from.
If the file you are opening is not a python file, then it will close upon finishing,regardless of what you declare from within python. If that is the case you could always try detaching it from it's parent using:
from subprocess import Popen, CREATE_NEW_PROCESS_GROUP
subprocess.Popen(["rv", rvFile, '-nc'], close_fds = True | CREATE_NEW_PROCESS_GROUP)
This is specifically for running the python script as a commandline process, but I eventually got this working by combining two answers that people suggested.
Using the combination of DETACHED_PROCESS suggested in this answer worked for running it through IDLE, but the commandline interface. But using shell=True (as ajsp suggested) and the DETACHED_PROCESS parameter it allows me to close the python script window and leave the other program still running.
DETACHED_PROCESS = 0x00000008
pid = subprocess.Popen(["rv", rvFile, '-nc'], creationflags=DETACHED_PROCESS, shell=True).pid
raw_input("= Opened file")

Categories