Reputation: 271
I'm still very new to Python and am still wrapping my head around everything it can do. I'm currently working on a small app to help me in my job. It's got a graphical menu that lets me choose apps to install on a PC. The problem I have is some of the buttons have two installers that they run (32 and 64 bit). I need the program to wait for one to be finished before starting the next one. How do I do this?
Here's the code...
def retranslateUi(self, Form):
Form.setWindowTitle(_translate("Form", "Form", None))
self.label.setText(_translate("Form", "What would you like to install?", None))
self.adobe_reader.setText(_translate("Form", "Adobe Reader", None))
self.flash.setText(_translate("Form", "Flash", None))
self.java_7.setText(_translate("Form", "Java 7", None))
self.java_8.setText(_translate("Form", "Java 8", None))
self.adobe_reader.clicked.connect(self.adobe)
self.flash.clicked.connect(self.flash13)
self.java_7.clicked.connect(self.java7)
self.java_8.clicked.connect(self.java8)
def adobe(self):
os.startfile("C:\\Users\\Erik\\Desktop\\install_reader_11.exe")
def flash13(self):
os.startfile("C:\\Users\\Erik\\Desktop\\install_flash_13_IE.exe")
os.startfile("C:\\Users\\Erik\\Desktop\\install_flash_13_nonIE.exe")
def java7(self):
os.startfile("C:\\Users\\Erik\\Desktop\\install_java-7u71-x32.exe")
os.startfile("C:\\Users\\Erik\\Desktop\\install_java-7u71-x64.exe")
def java8(self):
os.startfile("C:\\Users\\Erik\\Desktop\\install_java-8u25-x32.exe")
os.startfile("C:\\Users\\Erik\\Desktop\\install_java-8u25-x64.exe")
Here's the edited code after I made the changes from Steve... also an error message I get in the python terminal after running an installer (which seems to work).
def adobe(mycmd):
mycmd = r"C:\Users\Erik\Desktop\install_reader_11.exe"
try:
retcode = call(mycmd,shell = True)
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", -retcode
else:
print >>sys.stderr, "Child returned", retcode
except OSError as e:
print >>sys.stderr, "Execution failed:", e
retcode = -1
return retcode
def flash13(mycmd):
mycmd = r"C:\Users\Erik\Desktop\install_flash_13_IE.exe"
try:
retcode = call(mycmd,shell = True)
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", -retcode
else:
print >>sys.stderr, "Child returned", retcode
except OSError as e:
print >>sys.stderr, "Execution failed:", e
retcode = -1
return retcode
Error Msg...
print >> sys.stderr, "Child returned", retcode
TypeError: unsupported operand type(s) for >>: 'builtin_function_or_method' and
'_io.TextIOWrapper'
Thanks!
Upvotes: 1
Views: 2974
Reputation: 8547
Everywhere that you're using os.startfile(cmd)
use subprocess.call(cmd)
. At the top of your script put
import subprocess
And change everywhere that has
os.startfile("C:\\Users\\Erik\\Desktop\\whatever.exe")
to
subprocess.call("C:\\Users\\Erik\\Desktop\\whatever.exe")
The problem with using os.startfile
for your script is that it is not blocking. That means that your script does not wait for the user to interact with the installers that pop up; it just keeps going, and it can pop up several installers at once. subprocess.call
is blocking. That means that it waits for whatever you launch to be finished, and your script will start right back up when the installer is closed.
Upvotes: 3
Reputation: 28370
Rather than os.startfile use something like the following example, I would put it into a function:
early in your code you need:
from subprocess import call
def SafeExtern(mycmd):
""" Wrapper to call external programs checking the results """
try: # This allows exceptions to be caught
retcode = call(mycmd, shell=True) # Call the external program
if retcode < 0: # Check the return code errors should be <0
print >>sys.stderr, "Child was terminated by signal", -retcode
else:
print >>sys.stderr, "Child returned", retcode # For information
except OSError as e: # Catch OSErrors and let the user know
print >>sys.stderr, "Execution failed:", e
retcode = -1 # Obviously this is an error
return retcode
You can then use the above function to call external programs waiting for the result in each case.
Note that if you prefix each string with r you can get rid of the double backslashes, e.g.:
r"C:\Users\Erik\Desktop\install_java-7u71-x32.exe"
rather than
"C:\\Users\\Erik\\Desktop\\install_java-7u71-x32.exe"
Upvotes: 1