Reputation: 411
I am using a python script to automate a process involving batch files. These are batch files that are used for other applications and I am not allowed to edit them.
At the end of the batch file, it prompts the following:
"Press any key to continue ..."
How do I use python to recognize when this prompt appears, and how do I respond to it? I want to be able to close the file so I can run the next batch file.
Currently I have found the following solution, but it's terrible and makes me feel dirty inside:
#Run the batch file with parameter DIABFile
subprocess.Popen([path + '\\' + batchFile, path + '\\' + DIABFile])
#Sit here like an idiot until I'm confident the batch file is finished
time.sleep(4)
#Press any key
virtual_keystrokes.press('enter')
Any ideas?
p = subprocess.Popen([path + '\\' + batchFile, path + '\\' + DIABFile],
bufsize=1, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
while p.poll() is None:
line = p.stdout.readline()
print(line)
if line.startswith('Press any key to continue'):
p.communicate('\r\n')
Resulted in the following output and error:
b'\r\n'
Traceback (most recent call last):
File "C:\workspace\Perform_QAC_Check\Perform_QAC_Check.py", line 341, in <module>
main()
File "C:\workspace\Perform_QAC_Check\Perform_QAC_Check.py", line 321, in main
run_setup_builderenv(sandboxPath, DIABFile)
File "C:\workspace\Perform_QAC_Check\Perform_QAC_Check.py", line 126, in run_setup_builderenv
if line.startswith('Press any key to continue'):
TypeError: startswith first arg must be bytes or a tuple of bytes, not str
The process tried to write to a nonexistent pipe.
The part that seemed weirdest to me was that the startswith first arg must be bytes or a tuple of bytes, not str. I looked up the documentation and it definitely should be a string? tutorial of startswith
So I looked online and found this little bit.
The error message seems to be a bug in Python, as it is exactly the other way around. But still, no problems here, add after line #75 in indian.py
try:
line = line.decode()
except AttributeError:
pass
And so I did.
p = subprocess.Popen([path + '\\' + batchFile, path + '\\' + DIABFile],
bufsize=1, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
while p.poll() is None:
line = p.stdout.readline()
print(line)
try:
line = line.decode()
if line.startswith('Press any key to continue'):
p.communicate('\r\n')
except AttributeError:
pass
Resulted in the following output:
b'\r\n'
b'Build Environment is created.\r\n'
b'\r\n'
b'Please Refer to the directory: C:/directory\r\n'
b'\r\n'
And then it hangs there... That is the last output before the "Please press any key to continue" should show up, but it never does.
I have since taken the second script and asked it to find "Please Refer", which it does. Unfortunately, then the script hangs again at the line:
p.communicate('\r\n')
Ending the program, again, prints the error:
The process tried to write to a nonexistent pipe.
Which I believe is related to this bug.
I can't imagine what I'm trying to do is THAT out of the ordinary. Since this is seemingly a little more complicated than expected I would like to say I am using XP and Python version 3.3.
Upvotes: 4
Views: 4928
Reputation: 305
As stated in the OP, none of the solutions were solving the problem. So at the end the solution from Bryce solved the problem for me:
subprocess.call([path + '\\' + batchFile, path + '\\' + DIABFile], stdin=subprocess.DEVNULL)
Upvotes: 1
Reputation: 1
The solution from this post worked for me:
Try to execute
cmd.exe /c YourCmdFile < nul
YourCmdFile
- full path to your batch script
Upvotes: -2
Reputation: 121
You could parse the output of the subprocess and match on the "Press any key to continue" phrase to continue on.
See this thread: read subprocess stdout line by line especially what he posted as Update2
It might look like this:
import subprocess
proc = subprocess.Popen([path + '\\' + batchFile, path + '\\' + DIABFile],stdout=subprocess.PIPE)
for line in iter(proc.stdout.readline,''):
if (line.rstrip() == "Press any key to..":
break;
Upvotes: 1
Reputation: 208495
Something like the following should work:
p = subprocess.Popen([path + '\\' + batchFile, path + '\\' + DIABFile],
bufsize=1, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
while p.poll() is None:
line = p.stdout.readline()
if line.startswith('Press any key to continue'):
p.communicate('\r\n')
Upvotes: 4