OLE automation: Difference between revisions

From Rosetta Code
Content added Content deleted
(omit zkl)
No edit summary
Line 71: Line 71:
#include lib\ComDispatch.ahk
#include lib\ComDispatch.ahk
#include lib\ComVar.ahk</lang>
#include lib\ComVar.ahk</lang>

=={{header|M2000 Interpreter}}==
We can use Events, from declared objects and from objects that we get as result from methods, using WithEvents.
<lang M2000 Interpreter>
Module CheckAutomation {
ExitNow=false
Declare WithEvents Alfa "WORD.APPLICATION"
\\ minimize console
Title "Minimized- Waiting", 0
Wait 300
Print "ok"
With Alfa, "Visible", True
Function ALFA_QUIT {
Print "Why you close Word?"
ExitNow=True
}
M=0
Every 20 {
If ExitNow then exit
M++
If M>500 then exit
}
Try {
Method Alfa, "QUIT"
}
Declare Alfa Nothing
if ExitNow then {
Print format$("Finish {0:2} sec", M/1000)
} Else {
Print "Close Word manually"
}
\\ show again console
Title "ok"
}
CheckAutomation
</lang>


=={{header|Python}}==
=={{header|Python}}==

Revision as of 15:58, 2 July 2018

Task
OLE automation
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

Library: ComDispatch

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("python.server") 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

}

  1. Include ComRemote.ahk
  2. include lib\ComDispTable.ahk
  3. include lib\ComDispatch.ahk
  4. include lib\ComVar.ahk</lang>

M2000 Interpreter

We can use Events, from declared objects and from objects that we get as result from methods, using WithEvents. <lang M2000 Interpreter> Module CheckAutomation {

     ExitNow=false
     Declare WithEvents Alfa "WORD.APPLICATION"
     \\ minimize console
     Title "Minimized- Waiting", 0
     Wait 300
     Print "ok"
     With Alfa, "Visible", True
     Function ALFA_QUIT {
                 Print "Why you close Word?"
                 ExitNow=True
     }
     M=0
     Every 20 {
           If ExitNow then exit
           M++
           If M>500 then exit
     }
     Try {
           Method Alfa, "QUIT"
     }
     Declare Alfa Nothing
     if ExitNow then {
           Print format$("Finish  {0:2} sec", M/1000)
     } Else {
           Print "Close Word manually"
     }
     \\ show again console
     Title "ok"

} CheckAutomation </lang>

Python

Library: 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

  1. -*- 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.server"

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)

  1. autohotkey.exe ahkside.ahk
  2. python /c/Python26/Scripts/ipython.py -wthread -i pythonside.py
  3. must use -wthread otherwise calling com client hangs</lang>

client <lang Python>import win32com.client client = win32com.client.Dispatch("python.server") client.write("hello world")</lang>