The os.startfile() sometimes fails to open a URL under Windows. This recipe provides a dependable function for opening a URL.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
import os always_works = 0 def starturl(url, dwell=0, add_msg="", tempfile = "name_ending_in.html"): html = "<html><head>\r\n<meta http-equiv=refresh " html += 'content="%s; url=%s">' % (dwell, url) html += "\r\n</head><body bgcolor=#d0d0d0>\r\n" html += "<h2>Loading .... " html += "<a href=%s>%s</a>" % (url,url) html += "<p><h3>%s</h3>\r\n</body></html>" % add_msg emfile_open_flags = os.O_WRONLY+os.O_CREAT+os.O_TRUNC+os.O_BINARY emf = os.open(tempfile, emfile_open_flags) os.write(emf, html) os.close(emf) os.startfile(tempfile) if __name__ == '__main__': if always_works == 1: starturl("http://www.python.org") else: os.startfile("http://www.python.org")
With global variable "always_works" set to 0 (as shown), the sample code opens the python home page. Now, try running the Microsoft Photo Editor (at C:\Program Files\Common Files\Microsoft Shared\PhotoEd\PHOTOED.EXE in Win XP) and leaving it open. The python home page does not open. The startfile on the last line of the code does not always work.
Change the global variable "always_works" to 1 and the sample code opens the python home page without interference.
Experimentation, shows the underlying shellexecute function is sometimes blocked when called by a URL, rather than a file. This affects the os.startfile() function on the Windows platform.
The os.startfile function works often enough that you can end up deploying code based on using it for opening a URL. ... but it will fail in the field.
The proposed starturl() substitute, works by opening an html file which re-directs to the intended URL. As submitted, the starturl() leaves a visible artifact on the screen momentarily. ... but it works since the underlying shellexecute does not have to resolve the URL.
To make starturl() thread safe, supply a different file name for the "tempfile" parameter for each thread.
It should be noted that the designation "always_works" is not true for Windows 98 and is true only for Windows 2000 and XP. A different solution is needed for Windows 98 (or Windows 95 with Internet Explorer 4.0 minimum installed). For the Win9x OS's, os.startfile() of a URL simply does not work, period. Rather, you must use os.system(batch_file.bat) where the batch_file.bat contains something like:
.... EXPLORER.EXE bin\w98\name_ending_in.html .... exit
Further, unless you want a zombied copy of the DOS session this invokes, you must have a PIF file named "batch_file" which has the following options set to non-default values: programs tab >> close on exit should be checked and Misc Tab >> Warn if still active unchecked.
ref: see http://www.developer.com/net/cplus/article.php/3380661 for related discussion of shellexecute failing with mix of .NET and MFC.