NAME

Win32::OLE - OLE Automation extensions

SYNOPSIS

$ex = Win32::OLE->new('Excel.Application') or die "oops\n";
$ex->Amethod("arg")->Bmethod->{'Property'} = "foo";
$ex->Cmethod(undef,undef,$Arg3);
$ex->Dmethod($RequiredArg1, {NamedArg1 => $Value1, NamedArg2 => $Value2});

$wd = Win32::OLE->GetObject("D:\\Data\\Message.doc");
$xl = Win32::OLE->GetActiveObject("Excel.Application");

DESCRIPTION

This module provides an interface to OLE Automation from Perl. OLE Automation brings VisualBasic like scripting capabilities and offers powerful extensibility and the ability to control many Win32 applications from Perl scripts.

The Win32::OLE module uses the IDispatch interface exclusively. It is not possible to access a custom OLE interface. OLE events and OCX's are currently not supported.

Methods

Win32::OLE->new(PROGID [, DESTRUCTOR])

OLE Automation objects are created using the new() method, the second argument to which must be the OLE program id or class id of the application to create. Return value is undef if the attempt to create an OLE connection failed for some reason. The optional third argument specifies a DESTROY-like method. This can be either a CODE reference or a string containing an OLE method name. It can be used to cleanly terminate OLE objects in case the Perl program dies in the middle of OLE activity.

The object returned by the new() method can be used to invoke methods or retrieve properties in the same fashion as described in the documentation for the particular OLE class (eg. Microsoft Excel documentation describes the object hierarchy along with the properties and methods exposed for OLE access).

Optional parameters on method calls can be omitted by using undef as a placeholder. A better way is to use named arguments, as the order of optional parameters may change in later versions of the OLE server application. Named parameters can be specified in a reference to a hash as the last parameter to a method call.

Properties can be retrieved or set using hash syntax, while methods can be invoked with the usual perl method call syntax. The keys and each functions can be used to enumerate an object's properties. Beware that a property is not always writable or even readable (sometimes raising exceptions when read while being undefined).

If a method or property returns an embedded OLE object, method and property access can be chained as shown in the examples below.

Win32::OLE->GetActiveObject(CLASS)

The GetActiveObject class method returns an OLE reference to a running instance of the specified OLE automation server. It returns undef if the server is not currently active. It will croak if the class is not even registered.

Win32::OLE->GetObject(MONIKER)

The GetObject class method returns an OLE reference to the specified object. The object is specified by a pathname optionally followed by additional item subcomponent separated by exclamation marks '!'.

Win32::OLE->Initialize(COINIT)

The Initialize class method can be used to specify an alternative apartment model for the Perl thread. It must be called before the first object is created. Valid values for COINIT are:

Win32::OLE::COINIT_APARTMENTTHREADED - single threaded
Win32::OLE::COINIT_MULTITHREADED     - the default
Win32::OLE::COINIT_OLEINITIALIZE     - single threaded, additional OLE stuff

COINIT_OLEINITIALIZE is sometimes needed when an OLE object uses additional OLE compound document technologies not available from the normal COM subsystem (for example MAPI.Session seems to require it). Both COINIT_OLEINITIALIZE and COINIT_APARTMENTTHREADED create a hidden top level window and a message queue for the Perl process. This may create problems with other application, because Perl normally doesn't process its message queue. This means programs using synchronous communication between applications (such as DDE initiation), may hang until Perl makes another OLE method call/property access or terminates. This applies to InstallShield setups and many things started to shell associations. Please try to utilize the Win32::OLE->SpinMessageLoop and Win32::OLE->Uninitialize methods if you can not use the default COINIT_MULTITHREADED model.

OBJECT->Invoke(METHOD,ARGS)

The Invoke object method is an alternate way to invoke OLE methods. It is normally equivalent to $OBJECT-METHOD(@ARGS)>. This function must be used if the METHOD name contains characters not valid in a Perl variable name (like foreign language characters). It can also be used to invoke the default method of an object even if the default method has not been given a name in the type library. In this case use <undef> or '' as the method name. To invoke an OLE objects native Invoke method (if such a thing exists), please use:

$Object->Invoke('Invoke', @Args);
Win32::OLE->LastError()

The LastError class method returns the last recorded OLE error. This is a dual value like the $! variable: in a numeric context it returns the error number and in a string context it returns the error message.

The last OLE error is automatically reset by a successful OLE call. The numeric value can also explicitly be set by a call (which will discard the string value):

Win32::OLE->LastError(0);
Win32::OLE->QueryObjectType(OBJECT)

The QueryObjectType class method returns a list of the type library name and the objects class name. In a scalar context it returns the class name only. It returns undef when the type information is not available.

OBJECT->SetProperty(NAME,ARGS,VALUE)

The SetProperty method allows to modify properties with arguments, which is not supported by the hash syntax. The hash form

$Object->{Property} = $Value;

is equivalent to

$Object->SetProperty('Property', $Value);

Arguments must be specified between the property name and the new value. It is not possible to use "named argument" syntax with this function because the new value must be the last argument to SetProperty.

This method hides any native OLE object method called SetProperty. The native method will still be available through the Invoke method:

$Object->Invoke('SetProperty', @Args);
Win32::OLE->SpinMessageLoop

This class method retrieves all pending messages from the message queue and dispatches them to their respective window procedures. Calling this method is only necessary when not using the COINIT_MULTITHREADED model. All OLE method calls and property accesses automatically process the message queue.

Win32::OLE->Uninitialize

The Uninitialize class method uninitializes the OLE subsystem. It also destroys the hidden top level window created by OLE for single threaded apartments. All OLE objects will become invalid after this call! It is possible to call the Initialize class method again with a different apartment model after shutting down OLE with Uninitialize.

Whenever Perl does not find a method name in the Win32::OLE package it is automatically used as the name of an OLE method and this method call is dispatched to the OLE server.

There is one special hack built into the module: If a method or property name could not be resolved with the OLE object, then the default method of the object is called with the method name as its first parameter. So

my $Sheet = $Worksheets->Table1;
or
my $Sheet = $Worksheets->{Table1};

is resolved as

my $Sheet = $Worksheet->Item('Table1');

provided that the $Worksheets object doesnot have a Table1 method or property. This hack has been introduced to call the default method of collections which did not name the method in their type library. The recommended way to call the "unnamed" default method is:

my $Sheet = $Worksheets->Invoke('', 'Table1');

This special hack is disabled under use strict 'subs';.

Functions

The following functions are not exported by default.

in(COLLECTION)

If COLLECTION is an OLE collection object then in $COLLECTION returns a list of all members of the collection. This is a shortcut for Win32::OLE::Enum-All($COLLECTION)>. It is most commonly used in a foreach loop:

foreach my $value (in $collection) {
    # do something with $value here
}
valof(OBJECT)

Normal assignment of Perl OLE objects creates just another reference to the OLE object. The valof function explictly dereferences the object (through the default method) and returns the value of the object.

	my $RefOf = $Object;
	my $ValOf = valof $Object;
        $Object->{Value} = $NewValue;

Now $ValOf still contains the old value wheras $RefOf would resolve to the $NewValue because it is still a reference to $Object.

The valof function can also be used to convert Win32::OLE::Variant objects to Perl values.

with(OBJECT, PROPERTYNAME => VALUE, ...)

This function provides a concise way to set the values of multiple properties of an object. It iterates over its arguments doing $OBJECT-{PROPERTYNAME} = $VALUE> on each trailing pair.

Overloading

The Win32::OLE objects can be overloaded to automatically convert to their values whenever they are used in a bool, numeric or string context. This is not enabled by default. You have to request it through the OVERLOAD pseudoexport:

use Win32::OLE qw(in valof with OVERLOAD);

You can still get the original string representation of an object (Win32::OLE=0xDEADBEEF), e.g. for debugging, by using the overload::StrVal method:

print overload::StrVal($object), "\n";

Please note that OVERLOAD is a global setting. If any module enables Win32::OLE overloading then it's active everywhere.

Class Variables

$Win32::OLE::CP

This variable is used to determine the codepage used by all translations between Perl strings and Unicode strings used by the OLE interface. The default value is CP_ACP, which is the default ANSI codepage. It can also be set to CP_OEMCP which is the default OEM codepage. Both constants are not exported by default.

$Win32::OLE::LCID

This variable controls the locale idnetifier used for all OLE calls. It is set to LOCALE_NEUTRAL by default. Please check the Win32::OLE::NLS module for other locale related information.

$Win32::OLE::Warn

This variable determines the behavior of the Win32::OLE module when an error happens. Valid values are:

0	Ignore error, return undef
1	Carp::carp if $^W is set (-w option)
2	always Carp::carp
3	Carp::croak

The error number and message (without Carp line/module info) are available through the Win32::OLE-LastError> class method.

EXAMPLES

Here is a simple Microsoft Excel application.

	use Win32::OLE;

	# use existing instance if Excel is already running
	eval {$ex = Win32::OLE->GetActiveObject('Excel.Application')};
	die "Excel not installed" if $@;
	unless (defined $ex) {
	    $ex = Win32::OLE->new('Excel.Application', sub {$_[0]->Quit;})
		    or die "Oops, cannot start Excel";
	}
	
	# open an existing workbook
	$book = $ex->Workbooks->Open( 'test.xls' );
	
	# write to a particular cell
	$sheet = $book->Worksheets(1);
	$sheet->Cells(1,1)->{Value} = "foo";

        # write a 2 rows by 3 columns range
        $sheet->Range("A8:C9")->{Value} = [[ undef, 'Xyzzy', 'Plugh' ],
                                           [ 42,    'Perl',  3.1415  ]];

        # print "XyzzyPerl"
        $array = $sheet->Range("A8:B9")->{Value};
        print $array[0][1] . $array[1][1];

	# save and exit
	$book->Save;
	undef $book;
	undef $ex;

Please note the destructor specified on the Win32::OLE->new method. It ensures that Excel will shutdown properly even if the Perl program dies. Otherwise there could be a process leak if your application dies after having opened an OLE instance of Excel. It is the responsibility of the module user to make sure that all OLE objects are cleaned up properly!

Here is an example of using Variant data types.

use Win32::OLE;
$ex = Win32::OLE->new('Excel.Application', \&OleQuit) or die "oops\n";
$ex->{Visible} = 1;
$ex->Workbooks->Add;
$ovR8 = Variant(VT_R8, "3 is a good number");
$ex->Range("A1")->{Value} = $ovR8;
$ex->Range("A2")->{Value} = Variant(VT_DATE, 'Jan 1,1970');

sub OleQuit { 
    my $self = shift; 
    $self->Quit; 
}

The above will put value "3" in cell A1 rather than the string "3 is a good number". Cell A2 will contain the date.

Similarly, to invoke a method with some binary data, you can do the following:

$obj->Method( Variant(VT_UI1, "foo\000b\001a\002r") );

Here is a wrapper class that basically delegates everything but new() and DESTROY(). The wrapper class shown here is another way to properly shut down connections if your application is liable to die without proper cleanup. Your own wrappers will probably do something more specific to the particular OLE object you may be dealing with, like overriding the methods that you may wish to enhance with your own.

package Excel;
use Win32::OLE;

sub new {
    my $s = {};
    if ($s->{Ex} = Win32::OLE->new('Excel.Application')) {
	return bless $s, shift;
    }
    return undef;
}

sub DESTROY {
    my $s = shift;
    if (exists $s->{Ex}) {
	print "# closing connection\n";
	$s->{Ex}->Quit;
	return undef;
    }
}

sub AUTOLOAD {
    my $s = shift;
    $AUTOLOAD =~ s/^.*:://;
    $s->{Ex}->$AUTOLOAD(@_);
}

1;

The above module can be used just like Win32::OLE, except that it takes care of closing connections in case of abnormal exits. Note that the effect of this specific example can be easier accomplished using the optional destructor argument of Win32::OLE::new:

my $Excel = Win32::OLE->new('Excel.Application', sub {$_[0]->Quit;});

Note that the delegation shown in the earlier example is not the same as true subclassing with respect to further inheritance of method calls in your specialized object. See perlobj, perltoot and perlbot for details. True subclassing (available by setting @ISA) is also feasible, as the following example demonstrates:

#
# Add error reporting to Win32::OLE
#

package Win32::OLE::Strict;
use Carp;
use Win32::OLE;

use strict qw(vars);
use vars qw($AUTOLOAD @ISA);
@ISA = qw(Win32::OLE);

sub AUTOLOAD {
    my $obj = shift;
    $AUTOLOAD =~ s/^.*:://;
    my $meth = $AUTOLOAD;
    $AUTOLOAD = "SUPER::" . $AUTOLOAD;
    my $retval = $obj->$AUTOLOAD(@_);
    unless (defined($retval) || $AUTOLOAD eq 'DESTROY') {
	my $err = Win32::OLE::LastError();
	croak(sprintf("$meth returned OLE error 0x%08x",$err))
	  if $err;
    }
    return $retval;
}

1;

This package inherits the constructor new() from the Win32::OLE package. It is important to note that you cannot later rebless a Win32::OLE object as some information about the package is cached by the object. Always invoke the new() constructor through the right package!

Here's how the above class will be used:

use Win32::OLE::Strict;
my $Excel = Win32::OLE::Strict->new('Excel.Application', 'Quit');
my $Books = $Excel->Workbooks;
$Books->UnknownMethod(42);

In the sample above the call to UnknownMethod will be caught with

UnknownMethod returned OLE error 0x80020009 at test.pl line 5

because the Workbooks object inherits the class Win32::OLE::Strict from the $Excel object.

NOTES

Hints for Microsoft Office automation

Documentation

The object model for the Office applications is defined in the Visual Basic reference guides for the various applications. These are typically not installed by default during the standard installation. They can be added later by rerunning the setup program with the custom install option.

Class, Method and Property names

The names have been changed between different versions of Office. For example Application was a method in Office 95 and is a property in Office97. Therefore it will not show up in the list of property names keys %$object when querying an Office 95 object.

The class names are not always identical to the method/property names producing the object. E.g. the Workbook method returns an object of type Workbook in Office 95 and _Workbook in Office 97.

Moniker (GetObject support)

Office applications seem to implement file monikers only. For example it seems to be impossible to retrieve a specific worksheet object through GetObject("File.XLS!Sheet"). Furthermore, in Excel 95 the moniker starts a Worksheet object and in Excel 97 it returns a Workbook object. You can use either the Win32::OLE::QueryObjectType class method or the $object->{Version} property to write portable code.

Enumeration of collection objects

Enumerations seem to be incompletely implemented. Office 95 application don't seem to support neither the Reset() nor the Clone() methods. The Clone() method is still unimplemented in Office 97. A single walk through the collection similar to Visual Basics for each construct does work however.

Localization

Starting with Office 97 Microsoft has changed the localized class, method and property names back into English. Note that string, date and currency arguments are still subject to locale specific interpretation. Perl uses the system default locale for all OLE transaction whereas Visual Basic uses a type library specific locale. A Visual Basic script would use "R1C1" in string arguments to specify relative references. A Perl script running on a German language Windows would have to use "Z1S1". Set the $Win32::OLE::LCID class variable to an English locale to write portable scripts. This variable should not be changed after creating the OLE objects; some methods seem to randomly fail if the locale is changed on the fly.

SaveAs method in Word 97 doesn't work

This is an known bug in Word 97. Search the MS knowledge base for Word / Foxpro incompatibility. That problem applies to the Perl OLE interface as well. A workaround is to use the WordBasic compatibility object. It doesn't support all the options of the native method though.

$Word->WordBasic->FileSaveAs($file);

The problem seems to be fixed by applying the Office 97 Service Release 1.

Randomly failing method calls

It seems like modifying objects that are not selected/activated is sometimes fragile. Most of these problems go away if the chart/sheet/document is selected or activated before being manipulated (just like an interactive user would automatically do it).

Incompatibilities

There are some incompatibilities with the version distributed by Activeware (as of build 306).

  1. The package name has changed from "OLE" to "Win32::OLE".

  2. All functions of the form "Win32::OLEFoo" are now "Win32::OLE::Foo", though the old names are temporarily accomodated. Win32::OLECreateObject() was changed to Win32::OLE::CreateObject(), and is now called Win32::OLE::new() bowing to established convention for naming constructors. The old names should be considered deprecated, and will be removed in the next version.

  3. Package "OLE::Variant" is now "Win32::OLE::Variant".

  4. The Variant function is new, and is exported by default. So are all the VT_XXX type constants.

  5. The support for collection objects has been moved into the package Win32::OLE::Enum. The keys %$object method is now used to enumerate the properties of the object.

Bugs and Limitations

  1. To invoke a native OLE method with the same name as one of the Win32::OLE methods (Dispatch, Invoke, SetProperty, DESTROY, etc.), you have to use the Invoke method:

    $Object->Invoke('Dispatch', @AdditionalArgs);

    The same is true for names exported by the Exporter or the Dynaloader modules, e.g.: export, export_to_level, import, _push_tags, export_tags, export_ok_tags, export_fail, require_version, dl_load_flags, croak, bootstrap, dl_findfile, dl_expandspec, dl_find_symbol_anywhere, dl_load_file, dl_find_symbol, dl_undef_symbols, dl_install_xsub and dl_error.

  2. The class global variables $Win32::OLE::WARN and $Win32::OLE::LCID must currently be accessed directly. An API to manipulate these settings will be made available in the future.

SEE ALSO

The documentation for Win32::OLE::Const, Win32::OLE::Enum, Win32::OLE::NLS and Win32::OLE::Variant contains additional information about OLE support for Perl on Win32.

AUTHORS

Originally put together by the kind people at Hip and Activeware.

Gurusamy Sarathy <gsar@umich.edu> subsequently fixed several major bugs, memory leaks, and reliability problems, along with some redesign of the code.

Jan Dubois <jan.dubois@ibm.net> pitched in with yet more massive redesign, added support for named parameters, and other significant enhancements.

COPYRIGHT

    (c) 1995 Microsoft Corporation. All rights reserved. 
	Developed by ActiveWare Internet Corp., http://www.ActiveWare.com

    Other modifications Copyright (c) 1997, 1998 by Gurusamy Sarathy
    <gsar@umich.edu> and Jan Dubois <jan.dubois@ibm.net>

    You may distribute under the terms of either the GNU General Public
    License or the Artistic License, as specified in the README file.

VERSION

Version 0.10 9 September 1998