OLE automation: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
No edit summary
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(7 intermediate revisions by 5 users not shown)
Line 1:
{{task|OLE Automation Client and Server}}
[http://en.wikipedia.org/wiki/OLE_Automation OLE Automation]   is an inter-process communication mechanism based on   [http://en.wikipedia.org/wiki/Component_Object_Model 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.
;Task:
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 [http://en.wikipedia.org/wiki/Variant_type variants] to and from the native value types.
<br><br>
 
=={{header|AutoHotkey}}==
Line 9 ⟶ 15:
 
client: using the ahk ole server as well as the python ole server implemented below
<langsyntaxhighlight lang="autohotkey">ahk := comobjactive("ahkdemo.ahk")
ahk.hello("hello world")
py := ComObjActive("python.server")
py.write("hello")
return</langsyntaxhighlight>
server:
<langsyntaxhighlight lang="autohotkey">#Persistent
CLSID_ThisScript := "{38A3EB13-D0C4-478b-9720-4D0B2D361DB9}"
APPID_ThisScript := "ahkdemo.ahk"
Line 70 ⟶ 76:
#include lib\ComDispTable.ahk
#include lib\ComDispatch.ahk
#include lib\ComVar.ahk</langsyntaxhighlight>
 
=={{header|Go}}==
{{libheader|Go OLE}}
{{works with|Windows 10}}
<br>
This uses OLE automation to create a new Microsoft Word document, write some text to it and after 10 seconds close the document without saving and quit Word.
<syntaxhighlight lang="go">package main
 
import (
"time"
ole "github.com/go-ole/go-ole"
"github.com/go-ole/go-ole/oleutil"
)
 
func main() {
ole.CoInitialize(0)
unknown, _ := oleutil.CreateObject("Word.Application")
word, _ := unknown.QueryInterface(ole.IID_IDispatch)
oleutil.PutProperty(word, "Visible", true)
documents := oleutil.MustGetProperty(word, "Documents").ToIDispatch()
document := oleutil.MustCallMethod(documents, "Add").ToIDispatch()
content := oleutil.MustGetProperty(document, "Content").ToIDispatch()
paragraphs := oleutil.MustGetProperty(content, "Paragraphs").ToIDispatch()
paragraph := oleutil.MustCallMethod(paragraphs, "Add").ToIDispatch()
rnge := oleutil.MustGetProperty(paragraph, "Range").ToIDispatch()
oleutil.PutProperty(rnge, "Text", "This is a Rosetta Code test document.")
 
time.Sleep(10 * time.Second)
 
oleutil.PutProperty(document, "Saved", true)
oleutil.CallMethod(document, "Close", false)
oleutil.CallMethod(word, "Quit")
word.Release()
 
ole.CoUninitialize()
}</syntaxhighlight>
 
=={{header|M2000 Interpreter}}==
Line 76 ⟶ 118:
 
We can use Events, from declared objects and from objects that we get as result from methods, using WithEvents.
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module CheckAutomation {
ExitNow=false
Line 108 ⟶ 150:
}
CheckAutomation
</syntaxhighlight>
</lang>
 
=={{header|Phix}}==
Some Microsft Excel OLE automation routines can be found [http://phix.x10.mx/pmwiki/pmwiki.php?n=Main.ManageExcelFiles here] but since I don't have Excel installed I have not tested them.<br>
There are also some older (also untested) routines [http://phix.x10.mx/pmwiki/pmwiki.php?n=Main.CodeScrapsForMsExcelDocuments here].
 
=={{header|Python}}==
Line 114 ⟶ 160:
Server uses a client of the ahk server above to register the clsid in the windows registry.
Translated from <tt>win32com/test/testDynamic.py</tt>
<langsyntaxhighlight lang="python">#!/usr/bin/env python
# -*- coding: utf-8 -*-
import win32com.client
Line 169 ⟶ 215:
# autohotkey.exe ahkside.ahk
# python /c/Python26/Scripts/ipython.py -wthread -i pythonside.py
# must use -wthread otherwise calling com client hangs</langsyntaxhighlight>
client
<langsyntaxhighlight Pythonlang="python">import win32com.client
client = win32com.client.Dispatch("python.server")
client.write("hello world")</langsyntaxhighlight>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|WrenGo}}
{{libheader|Go OLE}}
{{works with|Windows 10}}
An embedded application with a Go host so we can use the Go OLE library.
<syntaxhighlight lang="wren">/* OLE_automation.wren */
 
class Ole {
foreign static coInitialize(p)
foreign static coUninitialize()
}
 
class OleUtil {
static createObject(programID) {
return IUnknown.new(programID)
}
 
foreign static putProperty(disp, name, param)
foreign static mustGetProperty(disp, name)
foreign static mustCallMethod(disp, name)
foreign static mustCallMethod2(disp, name, param)
}
 
foreign class GUID {
construct new(guid) {}
}
 
var IID_DISPATCH = GUID.new("{00020400-0000-0000-C000-000000000046}")
 
foreign class IUnknown {
construct new(programID) {}
 
foreign queryInterface(iid, name)
foreign static release(name)
}
 
class Time {
foreign static sleep(secs)
}
 
Ole.coInitialize(0)
var unknown = OleUtil.createObject("Word.application")
var word = unknown.queryInterface(IID_DISPATCH, "word")
OleUtil.putProperty(word, "Visible", true)
var documents = OleUtil.mustGetProperty(word, "Documents")
var document = OleUtil.mustCallMethod(documents, "Add")
var content = OleUtil.mustGetProperty(document, "Content")
var paragraphs = OleUtil.mustGetProperty(content, "Paragraphs")
var paragraph = OleUtil.mustCallMethod(paragraphs, "Add")
var range = OleUtil.mustGetProperty(paragraph, "Range")
 
OleUtil.putProperty(range, "Text", "This is a Rosetta Code test document.")
 
Time.sleep(10)
 
OleUtil.putProperty(document, "Saved", true)
OleUtil.mustCallMethod2(document, "Close", false)
OleUtil.mustCallMethod(word, "Quit")
IUnknown.release(word)
 
Ole.coUninitialize()</syntaxhighlight>
<br>
We now embed this script in the following Go program and run it.
<syntaxhighlight lang="go">/* go run OLE_automation.go */
 
package main
 
import (
ole "github.com/go-ole/go-ole"
"github.com/go-ole/go-ole/oleutil"
"strings"
"time"
wren "github.com/crazyinfin8/WrenGo"
)
 
type any = interface{}
 
var dispMap = make(map[string]*ole.IDispatch)
 
func coInitialize(vm *wren.VM, parameters []any) (any, error) {
p := uintptr(parameters[1].(float64))
ole.CoInitialize(p)
return nil, nil
}
 
func coUninitialize(vm *wren.VM, parameters []any) (any, error) {
ole.CoUninitialize()
return nil, nil
}
 
func putProperty(vm *wren.VM, parameters []any) (any, error) {
disp := dispMap[parameters[1].(string)]
propName := parameters[2].(string)
param := parameters[3]
oleutil.PutProperty(disp, propName, param)
return nil, nil
}
 
func mustGetProperty(vm *wren.VM, parameters []any) (any, error) {
disp := dispMap[parameters[1].(string)]
propName := parameters[2].(string)
disp2 := oleutil.MustGetProperty(disp, propName).ToIDispatch()
disp2Name := strings.ToLower(propName)
dispMap[disp2Name] = disp2
return disp2Name, nil
}
 
func mustCallMethod(vm *wren.VM, parameters []any) (any, error) {
dispName := parameters[1].(string)
disp := dispMap[dispName]
methName := parameters[2].(string)
disp2 := oleutil.MustCallMethod(disp, methName).ToIDispatch()
disp2Name := dispName[0:len(dispName)-1]
dispMap[disp2Name] = disp2
return disp2Name, nil
}
 
func mustCallMethod2(vm *wren.VM, parameters []any) (any, error) {
dispName := parameters[1].(string)
disp := dispMap[dispName]
methName := parameters[2].(string)
param := parameters[3]
disp2 := oleutil.MustCallMethod(disp, methName, param).ToIDispatch()
disp2Name := dispName[0:len(dispName)-1]
dispMap[disp2Name] = disp2
return disp2Name, nil
}
 
func newGUID(vm *wren.VM, parameters []any) (any, error) {
param := parameters[1].(string)
guid := ole.NewGUID(param)
return &guid, nil
}
 
func newIUnknown(vm *wren.VM, parameters []any) (any, error) {
programID := parameters[1].(string)
unknown, _ := oleutil.CreateObject(programID)
return &unknown, nil
}
 
func queryInterface(vm *wren.VM, parameters []any) (any, error) {
handle := parameters[0].(*wren.ForeignHandle)
ifc, _ := handle.Get()
unknown := ifc.(**ole.IUnknown)
handle2 := parameters[1].(*wren.ForeignHandle)
ifc2, _ := handle2.Get()
guid := ifc2.(**ole.GUID)
disp, _ := (*unknown).QueryInterface(*guid)
name := parameters[2].(string)
dispMap[name] = disp
return name, nil
}
 
func release(vm *wren.VM, parameters []any) (any, error) {
unknown := dispMap[parameters[1].(string)]
unknown.Release()
return nil, nil
}
 
func sleep(vm *wren.VM, parameters []any) (any, error) {
secs := time.Duration(parameters[1].(float64))
time.Sleep(secs * time.Second)
return nil, nil
}
 
func main() {
vm := wren.NewVM()
fileName := "OLE_automation.wren"
 
oleMethodMap := wren.MethodMap {
"static coInitialize(_)" : coInitialize,
"static coUninitialize()": coUninitialize,
}
 
oleUtilMethodMap := wren.MethodMap {
"static putProperty(_,_,_)" : putProperty,
"static mustGetProperty(_,_)" : mustGetProperty,
"static mustCallMethod(_,_)" : mustCallMethod,
"static mustCallMethod2(_,_,_)": mustCallMethod2,
}
 
iUnknownMethodMap := wren.MethodMap {
"queryInterface(_,_)": queryInterface,
"static release(_)" : release,
}
 
timeMethodMap := wren.MethodMap {
"static sleep(_)": sleep,
}
 
classMap := wren.ClassMap {
"Ole" : wren.NewClass(nil, nil, oleMethodMap),
"OleUtil" : wren.NewClass(nil, nil, oleUtilMethodMap),
"GUID" : wren.NewClass(newGUID, nil, nil),
"IUnknown" : wren.NewClass(newIUnknown, nil, iUnknownMethodMap),
"Time" : wren.NewClass(nil, nil, timeMethodMap),
}
 
module := wren.NewModule(classMap)
vm.SetModule(fileName, module)
vm.InterpretFile(fileName)
vm.Free()
}</syntaxhighlight>
 
{{omit from|Ada|Too involved to implement from scratch, and OS specific}}
Line 191 ⟶ 442:
{{omit from|PicoLisp}}
{{omit from|Retro}}
{{omit from|SQL PL|It does not handle COM}}
{{omit from|TPP}}
{{omit from|UNIX Shell}}<!--Wrong OS! -->
9,485

edits