COM automation, Internet Explorer, DocumentComplete event
I'm very new to Python and have a question concerning IE automation and detection of page completion. The MSDN article 180366 states in part: The top-level frame fires the DocumentComplete in the end. So, to check if a page is done downloading, you need to check if the IDispatch* parameter is same as the IDispatch of the WebBrowser control. For Visual Basic, here is code that performs this check: Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant) If (pDisp Is WebBrowser1.Object) Then Debug.Print "Web document is finished downloading" End If End Sub I'm able to catch IE's events including DocumentComplete with: def OnDocumentComplete(self, pDisp, URL): so i have pDisp. Self is the object returned by: self.ie = DispatchWithEvents("InternetExplorer.Application", InternetExplorerEvents) that created the automation object. How do I perform the test in Python? Thanks for any help. -- http://mail.python.org/mailman/listinfo/python-list
Where to report Python bug?
I'm very new to Python and have encountered what appears to be a bug when using com automation of IE with events. I get exception messages that look like this: pythoncom error: Python error invoking COM method. Traceback (most recent call last): File "C:\Python24\Lib\site-packages\win32com\server\policy.py", line 285, in _Invoke_ return self._invoke_(dispid, lcid, wFlags, args) File "C:\Python24\Lib\site-packages\win32com\server\policy.py", line 290, in _invoke_ return S_OK, -1, self._invokeex_(dispid, lcid, wFlags, args, None, None) File "C:\Python24\Lib\site-packages\win32com\server\policy.py", line 653, in _invokeex_ args, kwArgs = self._transform_args_(args, kwArgs, dispid, lcid, wFlags, serviceProvider) File "C:\Python24\Lib\site-packages\win32com\server\policy.py", line 648, in _transform_args_ arg = str(arg) exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 15: ordinal not in range(128) When navigating to certain URLs, for example http://projects.wri.org/project_content_text.cfm?ContentID=3587. The messages come as a consequence of an IE event which is being processed by the event class object. Where should this sort of thing be reported? Thanks for any help. -- http://mail.python.org/mailman/listinfo/python-list
Re: COM automation, Internet Explorer, DocumentComplete event
Without going into an overly long discussion, suffice to say that the busy attribute, notwithstanding Microsoft documentation to the contrary, simply doesn't work. BTW, there are a fair number of URLs for which PAMIE's combination of busy and readystate doesn't work. This scheme is somewhat better than both, but (of course it could only be) also doesn't work under some cases. Nevertheless, it's better than depending on busy or ready state. So how do I do the equivalent of pDisp Is WebBrowser1.Object in python? -- http://mail.python.org/mailman/listinfo/python-list
Re: COM automation, Internet Explorer, DocumentComplete event
Thanks very much Roger. As you might have guessed, I'm rather new to Python. The notion that == does the job illustrates one of the reason's I've undertaken learning yet another new language (40+ years on, the language count is rather larger than I'd care to admit). I should also mention the fact that a newsgroup post actually gets an answer is a big plus. Thanks again. I was in a bit of a rush in my post about busy. Let me take a minute to explain on the off chance that someone else might benefit. IE's busy attribute doesn't work for determining when a page has fully downloaded. It only indicates IE's internal work state. If you watch the event stream, busy, and readystate while pages are loading you often see busy go false and then go true again fairly quickly. So, busy as a reliable check for page completely loaded is a fairly poor choice. I mentioned PAMIE. It uses a technique that waits for busy false, then readystate complete. This is much better than simple busy, but suffers from two flaws. First the last time I looked at that PAMIE's code the checks were serial. So it can get confused by an early busy false, then go into it's readystate complete check inappropriately early. This aside, there are pages where during loading, busy is false and ready state complete for a short time then more page content is downloaded (watching the event stream from real world pages is a very informative experience when it comes to a page being complete). The technique suggested in the MS KB article, actually works fairly well for determining when the page is in fact fully downloaded as a result of the thing that started the navigation (lots of things other than navigate can cause navigations, BTW). It basically means that the browser has all the bytes associated with the page in hand. Unfortunately, it also fails (although rather less often than any technique involving either busy or readystate) when the page has script that mucks about with the DOM, causes additional activity over the web, etc. Thanks again. -- http://mail.python.org/mailman/listinfo/python-list
winguiauto
There seem to be a number of winguiauto(s) available on the net. Is there any 'offical' version? -- http://mail.python.org/mailman/listinfo/python-list
Re: winguiauto
You'll have to give me a bit of slack as I'm new to python. Much python development seems to be hosted on sourceforge. There are a couple of copies there with a number of modifications that seem to center on waiting for windows to exist. There is also the copy on Brunning's site without these modifications. I'm new to this, so I'm just asking as it's a bit unclear. -- http://mail.python.org/mailman/listinfo/python-list
DispatchWithEvents & PumpWaitingMessages
I'm working on a com automation project involving IE (yes, I know about Pamie). I connect to IE through DispatchWithEvents, start a navigation, and then loop calling PumpWaitingMessages. I see the events OK and all is well. At some point it is clear that the navigation is complete (at least insofar as IE is no longer generating events). The code then goes off and does something else for a bit NOT making calls to PumpWaitingMessages. A bit later, it is time to do another navigation. Now my question. The web page may have had some script that did stuff such as modifying the DOM, changing the status line, navigating to another URL, closing IE, etc. while messages were NOT being pumped. What happened to the messages? Are they queued waiting for the next PumpWaitingMessages call or what? -- http://mail.python.org/mailman/listinfo/python-list
com how to PumpWaitingMessages in a thread
When interfacing to a COM object, is it possible to pump messages in a thread? I'm working on an application that automates IE and needs to monitor IE events (yes I know about Pamie). I'm able to start IE as follows: ie = win32com.client.DispatchWithEvents( object, YamieEvents ) ie.event = win32event.CreateEvent(None,0,0,None) An earlier post by Mark Hammond suggested the ie.event line as a fix to an issue that seems to remain an issue in the current release. The class YamieEvents catches a number of events and outputs trace messages whenever an event occurs. It looks like this: class YamieEvents: def OnBeforeNavigate2(self, pDisp=defaultNamedNotOptArg, url=defaultNamedNotOptArg, Flags=defaultNamedNotOptArg, TargetFrameName=defaultNamedNotOptArg, PostData=defaultNamedNotOptArg, Headers=defaultNamedNotOptArg, Cancel=defaultNamedNotOptArg): out = 'OnBeforeNavigate2 URL [%s] \n' % url out += ' Flags [%s] \n' %`Flags` out += ' TargetFrameName [%s]' % TargetFrameName print out; # many more On event routines I'm able to navigate and wait as follows seeing the event trace: ie.Navigate(url) try: ie.Navigate(url) WaitMsg() except pythoncom.com_error, details: PrintFlush( "Warning - could not open %s"%url, details ) Where WaitMsg() looks like this: def WaitMsg(timeout=30, donetime=2000): # timeout in seconds, dontime in milliseconds! timeStart = time.time() timeTic = timeStart while True: rc = win32event.MsgWaitForMultipleObjects( (ie.event,), 0, donetime, win32event.QS_ALLEVENTS) if rc == win32event.WAIT_OBJECT_0: pass elif rc == win32event.WAIT_OBJECT_0+1: pythoncom.PumpWaitingMessages() elif rc == win32event.WAIT_TIMEOUT: PrintFlush( ' WaitMsg: got donetime' ) return True else: PrintFlush( 'Unrecognized event' ) timeNow = time.time() if timeNow - timeStart > timeout: PrintFlush( ' # got timeout' ) return False if timeNow - timeTic > 1: PrintFlush( '.', ) timeTic = timeNow So far everything seems to work fine. However, I've encountered a difficulty when dealing with web pages that have script that causes events AFTER the navigation is complete! Since the message pump is not being run, these events are not processed and IE appears to be hung (the script's page changes, navigations, etc. do no occur). I'm trying to work out how to run the message loop on a thread so that messages are continually pumped and these script modified pages are properly handled. Modeling a solution after Mark Hammond's Appendix D threads example I'm creating the message pump thread as follows: ie = win32com.client.DispatchWithEvents("InternetExplorer.Application", \ YamieEvents) ie.event = win32event.CreateEvent(None,0,0,None) ie.Visible = 1 WaitMsg() # now IE is up and google is displayed, there is good reason to think IE # is good and truely ready to be used #pass our ie com object to a thread to run the message loop # marshal the object object_stream = pythoncom.CoMarshalInterThreadInterfaceInStream( \ pythoncom.IID_IDispatch, ie ) args = (object_stream,) handle, id = win32process.beginthreadex( None, 0, PumpMessages, args, 0 ) The thread function looks like this: def PumpMessages(object_stream): pythoncom.CoInitialize()# initialize com for single thread # unmarshal the DispatchWithEvents object object = pythoncom.CoGetInterfaceAndReleaseStream( \ object_stream, pythoncom.IID_IDispatch) # convert to a useable DispatchWithEvents object ie = win32com.client.DispatchWithEvents( object, YamieEvents ) # without this line, MsgWaitForMultipleObjects reports no attribute event!? ie.event2 = win32event.CreateEvent(None,0,0,None) # now we should be in a position wait for events and pump messages timeStart = time.time() while True: rc = win32event.MsgWaitForMultipleObjects( (ie.event2,), 0, 1000, win32event.QS_ALLEVENTS) if rc == win32event.WAIT_OBJECT_0: PrintFlush( ' thread: event' ) elif rc == win32event.WAIT_OBJECT_0+1: PrintFlush( ' thread: pump' ) pythoncom.PumpWaitingMessages() elif rc == win32event.WAIT_TIMEOUT: PrintFlush( ' thread: tic' ) else: PrintFlush( ' thread: unrecognized event' ) if time.time() - timeStart > 40: PrintFlush( ' thread: got timeout' ) break # be a good citizen and cleanup self ie = None pythoncom.CoUninitialize() I've
Re: winguiauto
Thanks Simon. I looked at the other two and ended up using your version unmodified as the changes in watsup and pywinauto dealt with things unique to their needs. Your code still addresses basic needs and rather well at that. Regards -- http://mail.python.org/mailman/listinfo/python-list
pychecker
I'm new to pychecker. Some of my code generates the following No class attribute (HWND) found While HWND is not an attribute of the class, it IS an attribute of the instance created (my class is one of several classes used to create the new class). Can I use __pychecker__ to selectively supress this message? How? -- http://mail.python.org/mailman/listinfo/python-list