COM

Commands for accessing COM servers

SYNOPSIS

package require twapi

comobj PROGID_OR_CLSID ?options?
COMOBJ
COMOBJ NAME ?parameter ...?
COMOBJ -bind SCRIPT
COMOBJ -call METHOD ?parameter ...?
COMOBJ -destroy
COMOBJ -get PROPERTY ?parameter ...?
COMOBJ -interface
COMOBJ -iterate VARNAME SCRIPT
COMOBJ -print
COMOBJ -queryinterface IID
COMOBJ -set PROPERTY VALUE ?parameter ...?
COMOBJ -unbind BINDID
COMOBJ -with METHODLIST ?parameters ...?
timelist_to_variant_time TIMELIST
variant_time_to_timelist DOUBLE

DESCRIPTION

This module is still experimental and liable to change.

This module provides commands for supporting COM clients. TWAPI's COM support is limited to client side calls only and is not intended to compete with the OpTcl or TCOM packages. It was added to allow TWAPI access to some of the simpler COM based API's in Windows including WMI and ADSI.

Creation and Destruction of COM objects

A COM object can be created through the command comobj using the PROGID or CLSID of the corresponding COM class. This returns a Tcl command that may be used to access the object through subcommands.

When the object is no longer required, it must be explicitly destroyed by calling the command with the -destroy subcommand.

Properties and Methods

The properties and methods of a COM object can be accessed as subcommands of the Tcl command representing that object. The names of properties and methods can in theory overlap. Althouth TWAPI can usually figure out whether a property is being retrieved/set or a method is being called, you can explicitly control this by using the -get, -set or -call subcommands followed by the actual name. The following sequence of commands shows a sample session that drives Internet Explorer through its properties and methods.

Start up Internet Explorer (note it will not be visible yet)

set ie [comobj InternetExplorer.Application -enableaaa]

Make its window visible by changing its Visible property.

$ie Visible true

This could also have been written as

$ie -set Visible true

to explicitly indicate we want to set the property called Visible as opposed to making a call to the COM object's method of the same name (if there was one).

To go to the TWAPI home page, invoke the Navigate method

$ie Navigate http://twapi.sf.net

Get the LocationURL property to find the URL after redirection

$ie LocationURL

Not specifying any parameters gets the default value of the object. This is the property marked as the default value in the COM object's IDL definition.

$ie

Ask the application to exit by calling its Quit method.

$ie Quit

Finally, destroy the COM object.

$ie -destroy

COM Collections

Some COM objects are collection of items which may even be other COM objects. The items within these collections can be accessed by their index (which is not necessarily an integer) but it is often easier to iterate over them using the -iterate operator on the collection object. The following example illustrates this.

set fso_obj [comobj Scripting.FileSystemObject]
set drives_obj [$fso_obj Drives]
$drives_obj -iterate drive_obj {
    puts [$drive_obj DriveLetter]
    $drive_obj -destroy
}
$drives_obj -destroy
$fso_obj -destroy

The Drives method of the Scripting.FileSystemObject returns a collection drives_obj. The -iterate operator on the collection then loops through each item in the collection, assigning the item to drive_obj. In this case, each item is itself a COM object from which we get the DriveLetter property. Note that the drive_obj object generated in each iteration has to be explicitly destroyed.

Navigating Objects

In many cases, the desired objects have to be created by navigating through other objects. For example, the following example sets all cells within a range in a spreadsheet to 12345.

set xl [comobj Excel.Application]
$xl Visible true
set workbooks [$xl Workbooks]
set workbook [$workbooks Add]
set sheets [$workbook Sheets]
set sheet [$sheets Item 1]
set cells [$sheet range a1 c3]
$cells Value 12345
$cells -destroy
$sheet -destroy
$sheets -destroy
$workbook -destroy
$workbooks -destroy
$xl Quit
$xl -destroy

In the above example, in order to get to the range we have to navigate through a hierarchy of objects, starting with the application, the workbook collection, a workbook within the collection, the worksheets collection, a worksheet within that collection and finally the cell range. After setting the value, all the created objects have to be deleted.

As an alternative, the -with subcommand can be used to navigate through the intermediate objects as follows:

set xl [comobj Excel.Application]
$xl Visible true
$xl -with {
    Workbooks
    Add
    Sheets
    {Item 1}
    {range a1 c3}
} Value 12345
$xl -destroy

The -with subcommand takes a list of intermediate methods and associated parameters each of which should return a new object. Each element in the list is invoked on the previously created object and in turn should return a new COM object. The final object created from this list is passed the remaining arguments in the command. All intermediate objects are automatically destroyed.

COM Events

Some COM objects may generate notifications when certain events occur. A callback script may be registered using the -bind subcommand on a COMOBJ object. This script is invoked for every notification event generated by the COM object. The event name and parameters provided by the COM event source are appended to the script.

The following example receives events from Internet Explorer and prints them.

proc print_event args {puts "Received: [join $args ,]"}
set ie [comobj InternetExplorer.Application -enableaaa]
$ie Visible true
set bind_id [$ie -bind print_event]
$ie Navigate http://www.tcl.tk
after 2000
$ie -unbind $bind_id
$ie Quit
$ie -destroy

Note that the script is unregistered using the -unbind subcommand when no longer needed.

Commands

comobj PROGID_OR_CLSID ?options?
Creates a COM object and returns the name of a Tcl command that can be used to access it. PROGID_OR_CLSID is either the PROGID or the CLSID for the COM object.

The returned value COMOBJ is itself a Tcl command object that can be used to access the COM object. When the object is no longer required it should be deleted by calling the command with the -destroy subcommand. You should not delete the command simply by calling the Tcl rename command as this will lead to memory and resource leaks. options may contain one or more of the options in the table below. Refer to the CLSCTX documentation in the Windows SDK for details regarding these options.

-disablelog BOOLEAN If specified as true, disables logging of failures. Corresponds to the flag CLSCTX_NO_FAILURE_LOG in the SDK.
-download BOOLEAN If specified as true, allows downloading of code from the Internet or Directory Service. This corresponds to setting the flag CLSCTX_ENABLE_CODE_DOWNLOAD. If specified as false, disallows downloading of code from the Internet or Directory Service. This corresponds to setting the flag CLSCTX_DISABLE_CODE_DOWNLOAD.

If this option is not specified, neither of the flags is set in the underlying call to CoCreateInstance.
-enableaaa BOOLEAN If specified as true, enables activate-as-activator activations where a server process is launched under the caller's identity. This corresponds to setting the flag CLSCTX_ENABLE_AAA. If specified as false, disables activate-as-activator activations. This corresponds to setting the flag CLSCTX_DISABLE_AAA.

If this option is not specified, neither of the flags is set in the underlying call to CoCreateInstance.
-model MODELLIST Specifies which of the COM hosting models are acceptable. MODELLIST must be a list containing one or more of the symbols localserver, remoteserver, inprocserver, inprochandler, or any signifying any model is acceptable.
-nocustommarshal BOOLEAN If true, the object creation will fail if it uses custom marshalling. Corresponds to the flag CLSCTX_NO_CUSTOM_MARSHAL.


COMOBJ
Without any arguments, returns the value of the default property of the COM object.

COMOBJ NAME ?parameter ...?
The command interprets NAME as a property or method name of the COM object. In case of ambiguity (the object has read and write properties or a method of the same name), the command is interpreted as a property get if no additional parameters are specified, as a property put if exactly one additional parameters is specified and a method invocation otherwise.

COMOBJ -bind SCRIPT
Registers SCRIPT as a script to be invoked in the global scope whenever COMOBJ generates an event notification. The name of the event and any additional parameters in the notification are appended to the script.

The command returns an id. This id must be passed to the -unbind subcommand to unregister the script.

The binding is automatically deleted when COMOBJ is destroyed or may be removed explicitly through the -unbind subcommand.

See COM Events for an example.

COMOBJ -call METHOD ?parameter ...?
Calls the specified COM object method with the given parameters and returns the result if any.

COMOBJ -destroy
Destroys the COM object, removing any bindings and releasing resources.

COMOBJ -get PROPERTY ?parameter ...?
Returns the value of the specified property. Optional parameters may be specified if the property is an indexed property.

COMOBJ -interface
Returns the internal IDispatch pointer. Used for debugging purposes.

COMOBJ -iterate VARNAME SCRIPT
Iterates over items in COMOBJ which must be a COM collection. In each iteration, SCRIPT is executed in the caller's context with VARNAME being set to the value of the current item.

Note that if the item is itself a COM object, VARNAME will contain the name of a TCL command corresponding to that object and must be destroyed when no longer needed (not necessarily within SCRIPT).

See COM Collections for an example.

COMOBJ -print
Prints to stdout the methods and properties of the object. Used for debugging.

COMOBJ -queryinterface IID
Queries the object for a pointer to another interface for the object. Returns a raw handle to the interface.

COMOBJ -set PROPERTY VALUE ?parameter ...?
Sets the value of the specified property. The optional parameters may be specified if the property is an indexed property.

COMOBJ -unbind BINDID
Deletes the COM event binding identified by BINDID.

COMOBJ -with METHODLIST ?parameters ...?
The -with subcommand takes a list of intermediate methods and associated parameters. Each element of this list should itself be a list the first element being the method or property name and remaining elements being the parameters to pass when that method/property is invoked. The method or property should return a new object and the next element in the list is invoked on the previously returned object. The final object created from this list is passed the remaining arguments in the command.

All the intermediate objects created are automatically destroyed.

See Navigating Objects for an example.

timelist_to_variant_time TIMELIST
Several COM applications store date and time information as type double with the integral part representing the number of days since an epoch and the fractional part representing the time in the day. This command converts TIMELIST to this format. TIMELIST must be a list of 7 elements representing the year, month, day, hour, minutes, seconds and milliseconds.

variant_time_to_timelist DOUBLE
Several COM applications store date and time information as type double with the integral part representing the number of days since an epoch and the fractional part representing the time in the day. This command takes such a time value and returns a list of 7 elements representing the year, month, day, hour, minutes, seconds and milliseconds.

COPYRIGHT

Copyright © 2006 Ashok P. Nadkarni