4

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?

Attempt #1

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.

Attempt #2

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.

Notes

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.

Community
  • 1
  • 1
Stoating
  • 411
  • 3
  • 6
  • 12
  • are you able to edit the batch-files? if so, just remove the "pause" command at the end and they should just exit – Betagan Jun 18 '13 at 16:17
  • If only it were that simple. Alas, I am not allowed to edit the batch file. Says so in the first sentence. – Stoating Jun 18 '13 at 16:22
  • then you have to go with polling all the output and parsing it, see the two answers below – Betagan Jun 18 '13 at 16:25

4 Answers4

4

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')
Andrew Clark
  • 202,379
  • 35
  • 273
  • 306
  • Thank you F.J.. I have tried using your process and the results are now added to my OP. – Stoating Jun 19 '13 at 15:18
  • I was able to use this to grab the last line of output from the .bat file. Unfortunately still wasn't able to get "press any key to continue" I believe due to the bug stated in the OP. I am, however, accepting this answer. – Stoating Jul 03 '13 at 12:18
1

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;
Community
  • 1
  • 1
Betagan
  • 121
  • 3
1

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)
Christian
  • 163
  • 1
  • 10
-2

The solution from this post worked for me:

Try to execute cmd.exe /c YourCmdFile < nul

YourCmdFile - full path to your batch script

Community
  • 1
  • 1