Get IHTMLDocument2 for UI Automation in Python
Some software embed ie control in win32 window as the User Interface, such as Internet Explorer_Server. We can hardly identify the html control inner Internet Explorer_Server through Spy++. So it takes a great pain to ui automation. This post, I will introduce a way for Internet Explorer_Server automation.
Get IHTMLDocument2 interface
Also see:http://support.microsoft.com/kb/249232
Here is my python implentment:
#!/usr/bin/env python
#coding:utf-8
__author__ = 'CoderZh'
import sys
# Important for multithreading
sys.coinit_flags = 0 # pythoncom.COINIT_MULTITHREADED
import win32com
import win32com.client
import win32gui
import win32con
import pythoncom
def getIEServer(hwnd, ieServer):
if win32gui.GetClassName(hwnd) == 'Internet Explorer_Server':
ieServer.append(hwnd)
if __name__ == '__main__':
#pythoncom.CoInitializeEx(0) # not use this for multithreading
mainHwnd = win32gui.FindWindow('windowclass', 'windowtitle')
if mainHwnd:
ieServers = []
win32gui.EnumChildWindows(mainHwnd, getIEServer, ieServers)
if len(ieServers) > 0:
ieServer = ieServers[0]
msg = win32gui.RegisterWindowMessage('WM_HTML_GETOBJECT')
ret, result = win32gui.SendMessageTimeout(ieServer, msg, 0, 0, win32con.SMTO_ABORTIFHUNG, 1000)
ob = pythoncom.ObjectFromLresult(result, pythoncom.IID_IDispatch, 0)
doc = win32com.client.dynamic.Dispatch(ob)
print doc.url
doc.all['id'].click()
#pythoncom.CoUninitialize()
#coding:utf-8
__author__ = 'CoderZh'
import sys
# Important for multithreading
sys.coinit_flags = 0 # pythoncom.COINIT_MULTITHREADED
import win32com
import win32com.client
import win32gui
import win32con
import pythoncom
def getIEServer(hwnd, ieServer):
if win32gui.GetClassName(hwnd) == 'Internet Explorer_Server':
ieServer.append(hwnd)
if __name__ == '__main__':
#pythoncom.CoInitializeEx(0) # not use this for multithreading
mainHwnd = win32gui.FindWindow('windowclass', 'windowtitle')
if mainHwnd:
ieServers = []
win32gui.EnumChildWindows(mainHwnd, getIEServer, ieServers)
if len(ieServers) > 0:
ieServer = ieServers[0]
msg = win32gui.RegisterWindowMessage('WM_HTML_GETOBJECT')
ret, result = win32gui.SendMessageTimeout(ieServer, msg, 0, 0, win32con.SMTO_ABORTIFHUNG, 1000)
ob = pythoncom.ObjectFromLresult(result, pythoncom.IID_IDispatch, 0)
doc = win32com.client.dynamic.Dispatch(ob)
print doc.url
doc.all['id'].click()
#pythoncom.CoUninitialize()
Multithreading
IHTMLDocument2 is thread safe, we can not use it in any other thread except the main thread by default. If you want to use it in multi threads, write these code at the top of your file, and remenber do not explicit call pythoncom.CoInitializeEx(0) and pythoncom.CoUninitialize() :# Important for multithreading
sys.coinit_flags = 0 # pythoncom.COINIT_MULTITHREADED
sys.coinit_flags = 0 # pythoncom.COINIT_MULTITHREADED
Also see:http://bytes.com/topic/python/answers/26897-multithreaded-com-server-problem
IHTMLDocument2 for UI Automation
Also see : http://msdn.microsoft.com/en-us/library/aa752574%28VS.85%29.aspx
Now, you can write your own UI Automation framework by IHTMLDocument2.