OLE Automation
4545603
225824745
2008-07-15T15:59:36Z
Jimaginator
74231
m
{{Cleanup|date=August 2006}}
In [[Microsoft Windows]] applications programming, '''OLE Automation''' (later renamed by [[Microsoft]] to just '''Automation''',<ref name="msdn-mfc">{{cite web|url=http://msdn2.microsoft.com/en-us/library/dt80be78.aspx|title=Automation (MFC)|author=Microsoft Corporation|work=[[MSDN]]}}</ref><ref>{{cite book|author=Kruglinski, David J.|authorlink=|coauthors=Wingo, Scott; Shepherd, George|year=1998|title=Programming Microsoft Visual C++ 6.0|edition=5th edition|chapter=Chapter 25: Automation|publisher=[[Microsoft Press]]|location=Redmond, WA|id=ISBN 1-57231-857-0}}</ref> although the old term remained in widespread use), is an [[inter-process communication]] mechanism based on [[Component Object Model]] (COM) that is intended for use by Scripting Languages -originally Visual Basic, but now many languages that run on Windows.<ref>{{cite web|url=http://www.cs.umd.edu/hcil/pda/thesis/pda/node14.html|author=Richard Potter|date=[[1999-04-18]]|title=OLE Automation|work=Interprocess Communication for End-User Programming}}</ref> It provides an infrastructure whereby applications called '''automation controllers''' can access and manipulate (i.e. set properties of or call methods on) shared '''automation objects''' that are exported by other applications. It supersedes [[Dynamic Data Exchange]] (DDE), an older mechanism for applications to control one another.<ref>{{cite web|url=http://gmccomb.com/vault/edge/ole.html|title=Using OLE Automation to Control WordPerfect|date=1997|author=Gordon McComb}} — McComb describes how to use OLE Automation instead of DDE to control [[WordPerfect]]</ref> As with DDE, in OLE Automation the automation controller is the "client" and the application exporting the automation objects is the "server".
==Usage==
Automation was designed with the ease of scripting in mind, so controllers often provide languages such as [[Visual Basic for Applications]] to end users, allowing them to control automation objects via scripts. Automation objects can be written in conventional languages such as [[C++]],<ref name="cpp">{{cite web|url=http://www.cgoakley.demon.co.uk/prog/oleaut.html|title=OLE Automation for C++ programmers|author=Chris Oakley}}</ref> but the C++ syntax for COM (and therefore Automation) is complex and not very programmer-friendly. In contrast, languages such as [[Visual Basic]] and [[Borland Delphi]] provide a convenient syntax for Automation which hides the complexity of the underlying implementation.
===Interfaces===
An Automation object is a COM object implementing the [[IDispatch]] interface (for details on interfaces and calling conventions, see [[Component Object Model]]). Automation objects are referred to as ''ActiveX objects'', while an application that manipulates an ActiveX object is referred to as an ''ActiveX Client''.<ref>{{cite web|url=http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/html/4e9d6769-d73e-4daa-88ef-3ab6fa9a1497.asp|title=Overview of Automation|author=Microsoft Corporation|work=[[MSDN]]}}</ref> This interface exposes four methods, the most important of which is <code>Invoke</code>. This method allows calling methods of a class by name, with an arbitrary number of parameters. Neither the name of the method nor the number (and exact types) of parameters need to be known at compile time, as it is the case for COM objects not supporting Automation; moreover, in scripting languages there is no "compile time" at all. This technique is called [[late binding]].
Most existing COM components are Automation-compliant and furthermore allow both late binding and traditional, compile-time [[early binding]]. This is achieved by implementing so-called ''dual interfaces'', which are interfaces derived from IDispatch. Generally, both late and early binding expose the same functionality for Automation clients; languages such as Visual Basic and Delphi, as well as some C++ libraries, which provide a higher level of abstraction for COM, make sure that all Automation components created in these languages correctly duplicate their interfaces with late and early binding.
Generally, implementing early binding is more troublesome {{Fact|date=June 2008}}. Late binding is slower, but more reliable, as it does not require binary compatibility between versions of the same component. For late binding, a client only needs to know the name (or [[CLSID]]) of the desired object and the names and parameters of methods it actually uses, while for early binding, the client needs to know the complete definition and identifier (IID) for every interface requested, as well as the exact position of each method in the interface [[vtable]]. This is, however, more a problem of COM in general rather than Automation, as early binding relies on traditional COM calling conventions.
Automation servers may be implemented as '''single-use''' or '''multi-use'''.<ref>{{cite web|url=http://publib.boulder.ibm.com/infocenter/db2luw/v8//topic/com.ibm.db2.udb.doc/ad/c0009414.htm|title=OLE automation routines in BASIC and C++|publisher=IBM|work=DB2: Application Development Guide: Programming Server Applications}}</ref> For the former, each client connects to an individual instance of the server, with an individual instance of its class factory. For the latter, many clients connect to a single server, sharing that server's class factory across all clients.
The servers for the automation objects may be either out-of-process executables or in-process [[dynamic-link library|DLL]]s.<ref name="perl">{{cite journal|url=http://www.foo.be/docs/tpj/issues/vol3_2/tpj0302-0008.html|title=Win32::OLE|author=Jan Dubois|journal=The Perl Journal|volume=3|issue=2|date=Summer 1998}}</ref>
===Type libraries===
In order to automate an application, the developer of an automation controller must know the object model that is employed by that application.<ref name="WR">{{cite web|url=http://webreference.com./js/column55/|title=OLE Automation in JavaScript|work=Doc JavaScript|work=WebReference|author=Yehuda Shiran and Tomer Shiran}} — despite the title, the article discusses [[JScript]] rather than [[JavaScript]]</ref> This requires that the developer of the application publicly document its object model. Development of automation controllers without knowledge of the target application's object model is "difficult to impossible".<ref>{{cite journal|url=http://pbdj.sys-con.com/read/170833.htm|title=OLE — Extending the Capabilities of PowerBuilder (Part 2)|author=Bruce Armstrong|date=[[2006-01-16]]|journal=PowerBuilder Developers' Journal|volume=12|issue=11}}</ref>
Because of these complications, Automation components are usually provided with ''type libraries'', which contain [[metadata]] about classes, interfaces and other features exposed by an object library. Interfaces are described in [[Microsoft Interface Definition Language]]. Type libraries can be viewed using various tools, such as the Microsoft OLE/COM Object Viewer (<code>oleview.exe</code>, part of the [[Microsoft Platform SDK]]) or the Object Browser in Visual Basic (up to version 6) and [[Visual Studio .NET]].
Also, type libraries are used to generate [[Proxy pattern]]/[[Method stub|stub]] code for interoperating between COM and other platforms, such as [[Microsoft .NET]] and [[Java (programming language)|Java]]. For instance, the .NET Framework [[Software development kit|SDK]] includes tools that can generate a proxy .NET DLL to access Automation objects using both early binding (with information about interfaces extracted from a type library) and late binding (via IDispatch, mapped to the .NET Reflection API), with the built-in .NET-to-COM bridge called [[COM Interop]].<ref name="interop">{{cite book|author=Appleman, Dan||year=2001|title=Moving to VB.NET: Strategies, Concepts, and Code|chapter=Chapter 15: COM Interop and Accessing the Win32 API|publisher=[[Apress]]|id=ISBN 1-893115-97-6}}</ref> While Java lacks built-in COM support, toolsets like [[JACOB]]<ref>{{cite web|url=http://danadler.com/jacob/|title=The JACOB Project|date=2004-10-17}}</ref> and jSegue<ref>{{cite web|url=http://jsegue.sourceforge.net/|title=jSegue|date=2005-12-14]]}}</ref> can generate proxy source code (consisting of two parts, a set of Java classes and a [[C++]] source for a [[Java Native Interface]] DLL) from type libraries. These solutions only work on Windows.
Microsoft has publicly documented the object model of all of the applications in [[Microsoft Office]],<ref>{{cite web|publisher=Microsoft Corporation|work=KnowledgeBase|title=How to find and use Office object model documentation|url=http://support.microsoft.com/?scid=kb;en-us;222101}}</ref> and some other software developers have also documented the object models of their applications. Object models are presented to automation controllers as type libraries, with their interfaces described in [[Object Description Language|ODL]].
===Language support===
Automation is available for a variety of languages, including, but not limited to:
*[[C (programming language)|C]]
*[[C++]] (directly or via a library like [[Microsoft Foundation Class Library|MFC]] or [[Active Template Library|ATL]])<ref name="cpp" />
*[[Visual Basic]] and [[Visual Basic for Applications]]
*[[Delphi programming language|Delphi]]<ref>{{cite web|url=http://delphi.about.com/od/kbcontrolole/|title=OLE Automation using Delphi|work=[[About.com]]}}</ref>
*[[Microsoft .NET]] languages<ref name="interop" />
*[[APL (programming language)|APL]] (most Windows versions)
*[[Java (programming language)|Java]] (only with third-party tools)
*[[JScript]]<ref name="WR" /> and [[VBScript]]
*[[Perl]]<ref name="perl" />
*[[PHP]]<ref>{{cite web|url=http://www.php.net/manual/en/ref.com.php|title=PHP: COM and .Net (Windows)|author=The PHP Group|date=2006-07-25}}</ref>
*[[PowerBuilder]]
*[[Python (programming language)|Python]] <ref>{{cite web|url=http://sourceforge.net/projects/pywin32/|title=Python for Windows Extensions|author=Mark Hammond}}</ref>
*[[Ruby programming language|Ruby]] (via the 'win32ole' library included in the standard Ruby 1.8.x or later distribution)
===Examples===
The following Perl code launches [[Microsoft Excel]], loads an existing document, gets the values of four cells, exits the application, and then displays (from within Perl) the four values it got.
<source lang="Perl">
# This program illustrates controlling Excel from within Perl
# adapted from: http://blazonry.com/perl/xl_oleauto.php
use strict;
use warnings;
use OLE; # OLE.pm module
my $xlfile = "c:\\workingdir\\Perl\\test.xls"; # supply a test xls or csv
# Make OLE connection: this creates an instance of an Excel server
my $xl = CreateObject OLE 'Excel.Application' || die $!;
# Set application visibility: 1 = visible; 0 = not visible
$xl->{'Visible'} = 1;
# Open Excel file
my $book = $xl->Workbooks->Open($xlfile);
# Setup active worksheet
my $sheet = $book->Worksheets(1);
# Retrieve values from worksheet
my $a1 = $sheet->Range("A1")->{'Value'};
my $b1 = $sheet->Range("B1")->{'Value'};
my $a2 = $sheet->Range("A2")->{'Value'};
my $b2 = $sheet->Range("B2")->{'Value'};
# Close it up
$xl->ActiveWorkbook->Close(0);
$xl->Quit();
print $a1, " ", $b1, "\n"; #1st row
print $a2, " ", $b2, "\n"; #2nd row
</source>
The following Visual Basic 6 (or VBA) code launches [[Microsoft Excel]], creates a new document, selects some cells, types "Hello World!" into cells A1:C6, and then shows the application window. It operates using late binding, but early binding can be enabled simply by changing the object type from <code>Object</code> (an alias for IDispatch) to <code>Excel.Application</code>, provided that the Excel type library is referenced in the project.
<source lang="vb">
Dim excelApp as Object
Set excelApp = CreateObject("Excel.Application")
excelApp.Workbooks.Add
excelApp.Range("A1:C6").Select
excelApp.ActiveCell.Formula = "Hello World!"
excelApp.Visible = True
</source>
Here is a sample code for C++, which just makes the window visible, using the pure COM API for late binding without other libraries or wrappers:
<source lang="cpp">
HRESULT hres;
CLSID clsid;
CLSIDFromProgID(L"Excel.Application", &clsid);
IDispatch *excelApp;
// Start Excel as a COM server in a separate process
hres = CoCreateInstance(clsid, 0, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void **)&excelApp);
if(FAILED(hres))
{
// error handling
}
DISPID dispidVisible;
OLECHAR *propertyName = "Visible";
hres = excelApp->GetIDsOfNames(IID_NULL, &propertyName, 1, LOCALE_SYSTEM_DEFAULT, &dispidVisible);
if(FAILED(hres))
{
// error handling
}
unsigned returnArg;
VARIANT varTrue;
DISPPARAMS params = { &varTrue, 1, 0, 0 };
// set the variant to a boolean true
varTrue.vt = VT_BOOL;
varTrue.boolVal = 0xFFFF;
// make the window visible: excelApp.Visible = True
hres = excelApp->Invoke(dispidVisible, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, params, 0, 0, &returnArg);
if(FAILED(hres))
{
// error handling
}
// ... use the object
// free the object
excelApp->Release();
</source>
Here is an example C++ code (doing the same as the Visual Basic code) using [[VOLE]] (http://vole.sourceforge.net/), which is a compiler-independent COM/Automation driver library:
<source lang="cpp">
using vole::object;
using vole::collection;
object excelApp = object::create("Excel.Application", CLSCTX_LOCAL_SERVER);
object workBooks = excelApp.get_property<object>(L"Workbooks");
workBooks.invoke_method<void>(L"Add");
object range = excelApp.get_property<object>(L"Range", "A1:C6");
range.invoke_method<void>(L"Select");
object activeCell = excelApp.get_property<object>(L"ActiveCell");
activeCell.put_property(L"Formula", "Hello World!");
excelApp.put_property(L"Visible", true);
</source>
Here is an example C++ code (doing the same as the Visual Basic code) using [[Microsoft Foundation Class Library|MFC]]-provided wrappers for Excel 97:
<source lang="cpp">
#include "excel8.h"
// ...
OleVariant covTrue((short)TRUE), covFalse((short)FALSE), covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
_Application excelApp;
if(!excelApp.CreateDispatch("Excel.Application"))
{
// error handling
}
excelApp.GetWorkbooks().Add(covOptional);
excelApp.GetRange(COleVariant("A1"),COleVariant("C6")).Select();
excelApp.GetActiveCell().SetFormula("Hello World!");
excelApp.SetVisible(TRUE);
</source>
Finally, here is an example for PHP5:
<source lang="php">
<?php
$excelApp = new COM("Excel.Application") or die("Cannot create an Excel object");
$excelApp->Workbooks->Add();
$excelApp->Range("A1:C6")->Select();
$excelApp->ActiveCell->Formula = "Hello World!";
$excelApp->Visible = 1;
?>
</source>
In [[C Sharp (programming language)|C#]] (and [[VB.NET]] with strict type checking) late binding is always explicit, producing code almost as complex as the pure C++ example. In contrast, early binding in .NET offers cleaner-looking code, like the other three examples (although the given examples implicitly involve late binding while .NET does not).
==Name confusion==
Automation objects do not necessarily use Microsoft OLE, which stands for [[Object Linking and Embedding]] — currently only a subset of COM — although some of Automation objects (which are a special type of COM objects<ref name="msdn-mfc" />) can be used in OLE and/or [[ActiveX]] environments. The confusion has its roots in Microsoft's earlier (rather vague) definition of OLE, which was previously more or less a synonym of COM — to the point that the acronym "OLE" frequently appears in legacy COM code, like parts of the [[Microsoft Foundation Class Library|MFC]] library.
==References==
{{reflist}}
== Further reading ==
===OLE Automation in general===
* {{cite book|
title=OLE 2 Programmer's Reference: Creating Programmable Applications with OLE Automation v. 2|
series=Programmer's Reference Library|
author=Microsoft Corporation|
publisher=Microsoft Press|
year=December 1993|
id=ISBN 1-55615-629-4}}
* {{cite book|
title=Inside OLE|
author=Kraig Brockschmidt|
publisher=Microsoft Press|
year=1995|
id=}}
* {{cite book|
title=OLE Automation Programmer's Reference|
series=Programmer's Reference Library|
author=Microsoft Corporation|
publisher=Microsoft Press|
year=1996|
id=ISBN 1-55615-851-3}}
===Object models for specific applications===
* {{cite book|
title=Microsoft Office 2000 Visual Basic for Applications Language Reference|
author=Microsoft Corporation|
publisher=Microsoft Press|
id=ISBN 1-57231-955-0}} — full printed documentation of the object model of Microsoft Office
==See also==
*[[Object linking and embedding]]
*[[Component Object Model]]
==External links==
*[http://www.skolob.co.uk/skolob/index.php?op=ViewArticle&articleId=5&blogId=1 OLE Automation] General paper on the introduction and problems implementing OLE.
*"[http://vole.sourceforge.net/ VOLE - A Neat C++ COM/Automation Driver]" — an open-source, compiler-independent C++ COM Automation driver library, for use when having to drive IDispatch directly. VOLE is highly robust, fully encapsulates all "low-level" aspects of IDispatch, and is very flexible, taking and returning normal C++ types.
{{FOLDOC}}
[[Category:Object-oriented programming]]
[[Category:Microsoft application programming interfaces]]
[[es:OLE Automation]]
[[fr:OLE Automation]]
[[pt:OLE Automation]]