""" 1. Generate ie6 module with win32/com/tools/readtlb.py from the ctypes package (I forget the details, but you can probably skip this and just use ie6_gen.py that comes with ctypes in the samples directory -- change the 'import ie6' below as appropriate.) 2. Generate a GUID and cut-n-paste it as PythonBHO._reg_clsid_. To generate a GUID using pywin32 (aka "Python for Windows Extensions"): import pythoncom pythoncom.CreateGUID() 3. python bho_skel.py /regserver 4. Use DebugView or similar to see the output from print statements. 5. Run IE, watch output (IIRC dispinterface_EventReceiver prints out messages for unimplemented events). 6. Remember to write something useful ;-) """ import sys import _winreg from ctypes import * from ctypes.com import IUnknown, PIUnknown, REFIID, GUID, STDMETHOD, HRESULT, \ COMObject from ctypes.com.automation import IDispatch, BSTR, VARIANT, \ dispinterface, DISPMETHOD from ctypes.com.register import Registrar from ctypes.com.connectionpoints import dispinterface_EventReceiver, \ GetConnectionPoint import ie6 # module generated by ctypes/com/tools/readtlb.py # _Logger is pinched from ctypes 0.6.2 # -------------------------------------------------------------------- from ctypes import windll kernel32 = windll.kernel32 # Hm. We cannot redirect sys.stderr/sys.stdout in the inproc case, # If the process is Python, the user would be pissed off if we did. class _Logger(object): # Redirect standard output and standard error to # win32 Debug Messages. Output can be viewed for example # in DebugView from www.sysinternals.com _installed = 0 _text = "" def write(self, text): self._text += str(text) if "\n" in self._text: kernel32.OutputDebugStringA(self._text) self._text = "" def install(cls): if cls._installed: return import sys sys.stdout = sys.stderr = cls() cls._installed = 1 install = classmethod(install) def isatty(self): return 0 # -------------------------------------------------------------------- _Logger.install() # redirect stdout to win32's OutputDebugStringA() HKLM = _winreg.HKEY_LOCAL_MACHINE BHO_KEY = ("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\" "Browser Helper Objects\\") class MyRegistrar(Registrar): def build_table(self): table = Registrar.build_table(self) table.extend([(HKLM, BHO_KEY+self._reg_clsid_, "", None)]) return table class IObjectWithSite(IUnknown): _iid_ = GUID("{FC4801A3-2BA9-11CF-A229-00AA003D7352}") IObjectWithSite._methods_ = IUnknown._methods_ + [ (STDMETHOD(HRESULT, "SetSite", PIUnknown)), (STDMETHOD(HRESULT, "GetSite", POINTER(c_void_p), REFIID))] class PythonBHO(COMObject): _reg_clsid_ = "{693D1AC0-2D77-11D8-9B9E-FB41F7E93A45}" _reg_progid_ = "PythonBHO" _com_interfaces_ = [IObjectWithSite] def _get_registrar(cls): return MyRegistrar(cls) _get_registrar = classmethod(_get_registrar) def IObjectWithSite_SetSite(self, this, pUnkSite): self.browser = POINTER(ie6.IWebBrowser2)() hr = pUnkSite.QueryInterface( byref(ie6.IWebBrowser2._iid_), byref(self.browser)) sink = DWebBrowserEvents2Impl() sink.handle = sink.connect(self.browser) class DWebBrowserEvents2Impl(dispinterface_EventReceiver): _com_interfaces_ = [ie6.DWebBrowserEvents2] def OnQuit(self, this, *args): self.disconnect(self.handle) def BeforeNavigate2(self, this, pDisp, url, Flags, TargetFrameName, PostData, Headers, Cancel): print "url", url if __name__ == '__main__': from ctypes.com.server import UseCommandLine UseCommandLine(PythonBHO)