Closing console application after completion from Python - python

I have an exe file that I have to call with several parameters, and for this purpose I use a bat file. After I execute bat file command prompt does not close, but wait for me to press a key. Now I have to run this exe several times, and for this I want to run a script that will do it for me.
i = 0
for path in Paths
outout = codecs.open('runExe.bat', 'w')
output.write(PathToExe + " -param1" + " -param2 " + param2Val[0] + " -param3 " + param3Val[0] + " -param4 " + param4Val[0] + " -param5 param5Val")
output.close()
subprocess.call(["regsvr32.exe", path, "-u", "-s"])
subprocess.call(["regsvr32.exe", path, "-s"])
subprocess.call("runExe.bat")
i + = 1
where param3Val, param4Val, param5Val are lists with values for related command prompt parameters.
When I call this bat file, everything works perfectly for the first fun of exe, but after it executes, command promt waits for my respond. When I press any key, it closes and then exe file starts with different parameters.
So I want to eliminate with key-pressing thing. I tried to put "exit" to the end of the bat file, but it did not work. How can I close command prompt window from script, when exe finishes working?
Thanks in advance!
Upd1: sarmold's way of doing thing works fine, but I think this it is exe (console application) that is waiting for my response. Smth in exe file prevents console window from closing, but I do not have access to sources. How can I close it's window after it executes?
Upd2: I have tried to add "shell" call after subprocess.call, but this does not seem to work either, still have to respond to the console manually :(
shell = win32com.client.Dispatch("WScript.Shell")
shell.AppActivate("Command Prompt")
shell.SendKeys("cls(ENTER)")

There are two possible approaches here:
Make only a single bat file that contains all your commands, including the regsvr32.exe commands, and execute that.
Have the Python script do everything for you.
For the first approach, use the "a" open mode to append to the batch file. (Perhaps delete it at script start.) Write the contents of your three commands to the batch file within the loop -- so you wind up with a long batch file that includes all the commands you need.
Then call the subprocess.call() command once, outside the loop, at the end of the script, to run the entire thing.
For the second approach, remove all the batch-file writing and run your PathToExe using Python's subprocess.call(). It's almost as simple as deleting all lines that work with output, but change output.write() to subprocess.call() -- and obviously, fiddle with the contents a little bit so they work for subprocess.call() directly.

Are you running this in a way that launches a command prompt every time you run runExe.bat? It shouldn't necessarily wait for you to close the console, but since it does, try running your script with subprocess.call("cmd /C runExe.bat").
#Arnold is right, though: It's better to simplify your set-up and (imho) just let python handle everything.

Related

How to remove "press enter to continue" when running Powershell within Python

Edited* Solution: Remove "pause".
I'm running a python script which calls upon powershell to execute a line of code:
def download():
subprocess.call('C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe yt-dlp https://www.youtube.com/watch?v=jtjnnykvnh4;pause', shell=True)
download()
The problem was that after executing, it would output "Press Enter to continue..." This interrupts the program.*in my original example I forgot to include the ";pause" which is what turned out to be what was causing the interruption in the program, as kindly pointed out by the marked answer.
Below is the fixed line of code which does not prompt "press enter to continue" after running:
def download():
subprocess.call('C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe yt-dlp https://www.youtube.com/watch?v=jtjnnykvnh4;kill $pid', shell=True)
download()
Apologies for confusion caused by the original post. Thanks for the help.
PowerShell normally exits unless you specify -NoExit at the commandline. Even then it will not include the message you are seeing unless you add a pause at the end instead. Even so, I would expect your command to look more like
'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe & {yt-dlp https://www.youtube.com/watch?v=jtjnnykvnh4}'
My guess this has more to do with Python, though I have not encountered it before...have you tried executing the PowerShell line from another commandline (cmd on Windows or bash on Linux/Mac or another favourite) to verify that you get the same result independently of Python?
Another possibility is that it is the yt-dlp tool that you are using that has the pause effect (I am not familiar with the tool). Is it a PowerShell module? Or is it something that can be run on the commandline and you don't need PowerShell as a middleman anyway? Would it have a "silent" or "-q" argument, or another more relevant argument?

Running multiple python scripts, one asking for input, does not allow input script to run. Also, how do I run simultaneous scripts(Python)

I have two python scripts, one that needs to continuously get input from the user and write into a file while the other simultaneously continuously check for updates from the file. My problem is that when running the check script, the os system terminal "position" seems to be already filled and I can not run the input script. It either shows the check scripts terminal or stays on a blinking cursor on the cmd terminal and not loading up. Also, I am unable to find a way to make both of the scripts run indefinitely until the user kills the process. Also, it might be my pc, but when running
while True:
check()
in my check script, it freezes my pc and also does not allow the input script to run
BTW, my pc had been having some problems, so I am going to reset it today and I hope that is the problem, but I have been going crazy over this problem and don't trust my judgement on this anymore:(
#my check script
def check():
with open('Tasks.txt','r') as file:
data = file.readlines()
if not "Neuron" in data and len(data)!=0:
i=0
Chars = data[0].split(" ")
while(i<len(Chars)):
c=0
print(len(data[0]))
print('Count:' + str(i))
print('Chars are ' + Chars[i])
while(c<len(Chars[i])):
Neuron.createNeuron(Chars[i][c-1:c])
c+=1
i+=1
data.pop(0)
Neuron.writeData('Tasks.txt',data,'w')
#os.system('py Create.py')
check()
#my user input script
def CM():
String = input(">")
#res = ' '.join(format(ord(x), 'b') for x in String)
#print(res)
Neuron.writeData('Logs.txt',Neuron.writeData('Tasks.txt',(' '.join(format(ord(x), 'b') for x in String)+'\n'),'a'),'a')
CM()
CM()
So, I found the answer. Originally both files actually could run, but one of them, the input file, had to be opened from the IDLE and then run there. To run them both simultaneously repetitively was to put
os.system('py Create.py')
at the end of the file. So it would run a new session of the py script.
Also, I imported a file that was not just functions but commands also and it ran them, which is why I was unable to use the Input script.

Call to several batch files through CMD doesn't block

I'm trying to call several install.bat files one after another with Python trough CMD.
It is necessary that each bat file be displayed in an interactive console window because it asks for some users instructions and that the python program only resume after each CMD process is resolved
Each install.bat file can take a pretty long time to finish its process.
My code is the following :
for game in games :
print("----------- Starting conversion for %s -----------" %game)
subprocess.call("start cmd /C " + "Install.bat", cwd=os.path.join(gamesDosDir,game), shell=True)
print("end")
But the console windows inside the shell are launched all at once and the "end" message appears event before any of them is finished, whereas I would like them appearing one by one and not go to the n+1 one until the n one is finished and the console window closed (either by user or automatically /K or /C then).
I understand this is some problems using CMD as call should be blocking. How to resolve that? Additionally, if possible how to keep it exactly the same and add 'Y' and 'Y' as default user input?
The most common way to start a batch file (or more generally a CLI command) if to pass it as an argument to cmd /c. After you comment I can assume that you need to use start to force the creation of a (new) command window.
In that case the correct way is to add the /wait option to the start command: it will force the start command to wait the end of its subprocess:
subprocess.call("start /W cmd /C " + "Install.bat", cwd=os.path.join(gamesDosDir,game),
shell=True)
But #eryksun proposed a far cleaner way. On Windows, .bat files can be executed without shell = True, and creationflags=CREATE_NEW_CONSOLE is enough to ensure a new console is created. So above line could simply become:
subprocess.call("Install.bat", cwd=os.path.join(gamesDosDir,game),
creationflags = subprocess.CREATE_NEW_CONSOLE)

Python's check_output method doesn't return output sometimes

I have a Python script which is supposed to run a large number of other scripts, each located within a subdirectory of the script's working directory. Each of these other scripts is supposed to connect to a game client and run an AI for that game. To make this run, I had to run each script over two separate threads (one for each player). The problem I'm having is that sometimes the scripts' output isn't captured. My run-code looks like this:
def run(command, name, count):
chdir(name)
output = check_output(" ".join(command), stderr = STDOUT, shell = True).split('\r')
chdir('..')
with open("results_" + str(count) + ".txt", "w") as f:
for line in output:
f.write(line)
The strange part is that it does manage to capture longer streams, but the short ones go unnoticed. How can I change my code to fix this problem?
UPDATE: I don't think it's a buffering issue because check_output("ls ..", shell = True).split('\n')[:-1] returns the expected result and that command should take much less time than the scripts I'm trying to run.
UPDATE 2: I have discovered that output is being cut for the longer runs. It turns out that the end of output is being missed for all processes that I run for some reason. This also explains why the shorter runs don't produce any output at all.

Why does my script stop executing commands after calling an .EXE?

Here is the relevant code from a Python script where a few commands are executed to copy an executable file and then execute it:
exe_file_path = os.getcwd() + r'\name_of_executable.exe'
temp_loc = os.environ['temp']
subprocess.Popen(r'copy %s %s' % (exe_file_path, temp_loc), shell=True)
exe_file_path = os.environ['temp'] + r'\name_of_executable.exe'
subprocess.Popen(r'start %s' % (exe_file_path), shell=True)
subprocess.Popen(r'del %s' % (exe_file_path), shell=True)
Currently, name_of_executable.exe only prints out text and then calls system("pause").
After the pause is executed, I push enter and I would assume the executable would close and the Python script would continue, but the last line of Python doesn't execute.
Is this because I'm using the TEMP folder? (I'm executing from a command prompt running as administrator. How do I get the script to work?
All programs will be immediately started one after another. Call communicate on each Popen object to wait for program termination.
Additionally, your use of format strings is unnecessarily dangerous. ['copy', exe_file_path, temp_loc] automatically escapes any strange characters in exe_file_path and temp_loc (and is easier to read).
By the way, Python has very good functions for copying and deleting files in shutil and os; there is no need to call shell programs for that.
And instead of concatenating strings to determine exe_file_path, you should use os.path.join (although this is not that important, since your program seems locked to Windows).

Categories