OLE automation: Difference between revisions
Line 78:
requires [http://sourceforge.net/projects/pywin32/ pywin32].
server uses a client of the ahk server above to register the clsid in the windows registry.
translated from win32com/test/testDynamic.py
<lang python>#!/usr/bin/env python
# -*- coding: utf-8 -*-
|
Revision as of 17:23, 24 July 2011
You are encouraged to solve this task according to the task description, using any language you may know.
OLE Automation is an inter-process communication mechanism based on Component Object Model (COM) on Microsoft Windows.
Provide an automation server implementing objects that can be accessed by a client running in a separate process. The client gets a proxy-object that can call methods on the object. The communication should be able to handle conversions of variants to and from the native value types.
AutoHotkey
by fincs:discussion
client: using the ahk ole server as well as the python ole server implemented below<lang autohotkey> ahk := comobjactive("ahkdemo.ahk") ahk.hello("hello world") py := ComObjActive("ahkdemo.python") py.write("hello") return </lang> server: <lang autohotkey>
- Persistent
CLSID_ThisScript := "{38A3EB13-D0C4-478b-9720-4D0B2D361DB9}" APPID_ThisScript := "ahkdemo.ahk" funcs := ["aRegisterIDs", "aGetObject", "aCallFunc", "hello"] server := ahkComServer(CLSID_ThisScript, APPID_ThisScript, funcs) return
aRegisterIDs(this, CLSID, APPID){ RegisterIDs(CLSID, APPID) }
hello(this, message){ msgbox % message } aGetObject(this, name){ global return %name% }
aCallFunc(this, func, args){ return %func%(args) }
- ahkcomserver()
ahkComServer(CLSID_ThisScript, APPID_ThisScript, funcs) { global serverReady server := object()
; CLSID_ThisScript := "{38A3EB13-D0C4-478b-9720-4D0B2D361DB9}" ; APPID_ThisScript := "Garglet.QueryServer" RegisterIDs(CLSID_ThisScript, APPID_ThisScript)
for i, func in funcs { str .= func . ", " } str := SubStr(str, 1, strlen(str) - 2)
myObj := ComDispatch("", str)
- Expose it
if !(hRemote := ComRemote(myObj, CLSID_ThisScript)) { MsgBox, 16, %A_ScriptName%, Can't remote the object! ExitApp }
server.CLSID := CLSID_ThisScript server.APPID := APPID_ThisScript server.hRemote := hRemote serverReady := 1
return server
}
- Include ComRemote.ahk
- include lib\ComDispTable.ahk
- include lib\ComDispatch.ahk
- include lib\ComVar.ahk
</lang>
Python
requires pywin32. server uses a client of the ahk server above to register the clsid in the windows registry. translated from win32com/test/testDynamic.py <lang python>#!/usr/bin/env python
- -*- coding: utf-8 -*-
import win32com.client from win32com.server.util import wrap, unwrap from win32com.server.dispatcher import DefaultDebugDispatcher from ctypes import * import commands import pythoncom import winerror from win32com.server.exception import Exception
clsid = "{55C2F76F-5136-4614-A397-12214CC011E5}" iid = pythoncom.MakeIID(clsid) appid = "python.client"
class VeryPermissive:
def __init__(self): self.data = [] self.handle = 0 self.dobjects = {} def __del__(self): pythoncom.RevokeActiveObject(self.handle) def _dynamic_(self, name, lcid, wFlags, args): if wFlags & pythoncom.DISPATCH_METHOD: return getattr(self,name)(*args) if wFlags & pythoncom.DISPATCH_PROPERTYGET: try: # to avoid problems with byref param handling, tuple results are converted to lists. ret = self.__dict__[name] if type(ret)==type(()): ret = list(ret) return ret except KeyError: # Probably a method request. raise Exception(scode=winerror.DISP_E_MEMBERNOTFOUND) if wFlags & (pythoncom.DISPATCH_PROPERTYPUT | pythoncom.DISPATCH_PROPERTYPUTREF): setattr(self, name, args[0]) return raise Exception(scode=winerror.E_INVALIDARG, desc="invalid wFlags") def write(self, x): print x return 0
import win32com.server.util, win32com.server.policy child = VeryPermissive() ob = win32com.server.util.wrap(child, usePolicy=win32com.server.policy.DynamicPolicy) try:
handle = pythoncom.RegisterActiveObject(ob, iid, 0)
except pythoncom.com_error, details:
print "Warning - could not register the object in the ROT:", details handle = None
child.handle = handle
ahk = win32com.client.Dispatch("ahkdemo.ahk") ahk.aRegisterIDs(clsid, appid)
- autohotkey.exe ahkside.ahk
- python /c/Python26/Scripts/ipython.py -wthread -i pythonside.py
- must use -wthread otherwise calling com client hangs
</lang> client<lang Python> import win32com.client client = win32com.client.Dispatch("python.client") client.write("hello world") </lang>