COM

Commands for COM clients

SYNOPSIS

package require twapi_com
clsid_to_progid CLSID
com_initialize_security ?options?
com_make_credentials USERNAME PASSWORD DOMAIN
com_security_blanket ?options?
comobj PROGID_OR_CLSID ?options?
COMOBJ NAME ?parameter ...?
COMOBJ -bind SCRIPT
COMOBJ -call METHOD ?parameter ...?
COMOBJ -callnamedargs METHOD ?parametername parameter...?
COMOBJ -default
COMOBJ -destroy
COMOBJ -dispid NAME
COMOBJ -get PROPERTY ?parameter ...?
COMOBJ -instanceof TYPENAME
COMOBJ -interface ADDREF
COMOBJ -isnull
COMOBJ -iterate ?-cleanup? VARNAME SCRIPT
COMOBJ -lcid ?LCID?
COMOBJ -print
COMOBJ -securityblanket ?BLANKET?
COMOBJ -set PROPERTY VALUE ?VALUE ...?
COMOBJ -unbind BINDID
COMOBJ -with METHODLIST ?parameters ...?
comobj? COMOBJ
comobj_destroy ?COMOBJ...?
comobj_idispatch IDISPATCH ?ADDREF? ?LCID?
comobj_instances
comobj_object DISPLAYNAME ?-interface IDispatch|IDispatchEx?
define_dispatch_prototypes IID PROTOTYPES
generate_code_from_typelib PATH ?options?
get_typelib_path_from_guid GUID MAJOR MINOR ?-lcid LCID?
iid_to_name IID
ITypeLibProxy_from_path PATH ?-registration REGOPT?
ITypeLibProxy_from_guid GUID MAJOR MINOR ?-lcid LCID?
name_to_iid INTERFACENAME
outvar VARNAME
progid_to_clsid PROGID
timelist_to_variant_time TIMELIST
unregister_typelib GUID MAJOR MINOR ?-lcid LCID?
variant_time_to_timelist DOUBLE
variant_value VARIANT RAW ADDREF LCID
variant_type VARIANT
vt_empty
vt_null

DESCRIPTION

This module provides commands for implementing COM clients in Tcl. For implementing COM servers, see the COM server module. Like other scripting languages such as VBScript and Javascript, TWAPI's COM support is focused on Automation objects through their IDispatch and IDispatchEx interfaces. This provides Tcl clients the ability to script Windows applications such as Microsoft Office and Internet Explorer as well as admistrative interfaces such as Active Directory and Windows Management Instrumentation.

This documentation is reference material that assumes familiarity with COM programming concepts such as COM interfaces, automation, PROGID and CLSID identifier types and so on. For more introductory material and a guide with examples, see the COM chapter in the Tcl on Windows online book.

COM API layers

TWAPI's COM support is implemented in layers:

  • At the lowest layer, TWAPI supports the raw Windows API calls such as IUnknown_QueryInterface or IDispatch_Invoke. It is not expected that applications will directly use these calls and they are not documented here. See the Windows Platform SDK for details of these calls.
  • At the next layer, TWAPI provides object wrappers around COM interfaces like IUnknown, IDispatch, ITypeInfo etc. They provide a more convenient programming interface as well as better efficiency by caching type information etc. They also provide access to type libraries and other system facilities.
  • The highest layer exposes COM automation servers through "proxy" objects created through the comobj command. All details of method lookup, type management and runtime dispatching are internally handled. The COM automation server's methods and properties are directly accessible to the application. In the rest of this documentation the proxy object and underlying COM automation object are both refered to as "object" unless the distinction is significant.

Creation and Destruction of automation objects

A COM automation proxy object is created through the command comobj using the PROGID or CLSID of the corresponding COM class. This returns a Tcl object command that may be used to access the object's methods and properties. The example below creates a proxy object using the PROGID for Internet Explorer.

set xl [comobj Excel.Application]

To attach to an existing COM instance instead of creating a new one, the -active option may be specified.

set xl [comobj Excel.Application -active]

The above command requires an instance of Excel to be running else an error is returned.

Alternatively, the comobj_object command can be used to bind to a COM object identified by its display name. For example, the following creates a COM object for an Excel file.

set xlso [comobj_object c:\\data\\myspreadsheet.xls]

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

The list of existing COM automation objects in the application can be retrieved with the comobj_instances command. The command comobj? can be used to check if a command is a COM object.

Accessing Properties and Methods of Automation Objects

The properties and methods of a COM object can be accessed through the proxy object returned by the comobj command. 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 1]

Automation objects can be associated with a default property that is retrieved if no property or method are specified. This is the property marked as the default value in the COM object's IDL definition. In TWAPI this default property can be accessed using the -default method on the object.

$ie -default

Properties can be directly retrieved and modified. For example, the following commands makes its window visible by changing its Visible property.

$ie Visible true

In theory, the names of properties and methods of an automation object can 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. So the above call 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

Again, we could specify this is a method call, not a property, by explicitly indicating that as follows:

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

Explicitly specifying -call may also be required to disambiguate between methods that are implemented within the TWAPI comobj command object and the actual COM automation object itself. For example, the method destroy destroys the command object. If the underlying automation object also had a destroy method, you would need to invoke it as

$ie -call destroy

To continue with the example, we can read the LocationURL property to find the URL after redirection

$ie LocationURL

Ask the application to exit by calling its Quit method.

$ie Quit

Finally, destroy the proxy object and release the underlying COM object,

$ie destroy

Named Arguments

Some COM object methods may have a large number of arguments. Usually, these have default values and do not need to be specified. However, sometimes you may want to specify one or two of these. In such cases, having to specify all preceding arguments by position can be cumbersome. Using named arguments makes this easier. To use named arguments, use -callnamedargs instead of -call. For example, suppose in the call above to Navigate, we wanted to specify the page to be displayed in a new window without specifying all intervening parameters. We could call it as follows:

$ie -callnamedargs Navigate url http://twapi.sf.net TargetFrameName _blank

In the above call, url and TargetFrameName are parameter names. The parameter names for a call are generally specified in the documentation for the object.

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) using the Item method as shown below.

set fso [comobj Scripting.FileSystemObject]
set drives [$fso Drives]
set cdrive [$drives Item c:]
puts "Drive C: is [lindex {{not ready} ready} [$cdrive IsReady]]"
$cdrive -destroy
$drives -destroy
$fso -destroy

In the above example, the Drives method of the Scripting.FileSystemObject object (implemented as an automation object by the Windows Shell) returns a collection drives. The drive letter c: is used to index into the collection object drives. As an alternative to explicit indexing in this fashion, TWAPI provides the -iterate method for iterating over all items in the collection. This is similar to the VBScript For each statement. The following example illustrates this.

set fso [comobj Scripting.FileSystemObject]
set drives [$fso Drives]
$drives -iterate drive {
    set drive_letter [$drive DriveLetter]
    if {[$drive IsReady]} {
        puts "Drive $drive_letter free space: [$drive FreeSpace]"
    } else {
        puts "Drive $drive_letter is not ready."
    }
    $drive -destroy
}
$drives -destroy
$fso -destroy

The -iterate operator on the collection then loops through each item in the collection, assigning the item to drive. In this case, each item is itself a COM automation object on which commands can be invoked. Note that the drive object generated in each iteration has to be explicitly destroyed. Alternatively, the -cleanup option can be specified which will automatically destroy the iteration object ($drive in above example) on each iteration.

Navigating Automation Objects

In many cases, the resource represented by a COM object has to be accessed by navigating through multiple intermediary 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 Value2 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, TWAPI automation proxy objects provide the -with internal method to simplify this process:

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

The -with method takes a list of intermediate methods and associated parameters each of which should return a new object. Each method in the method list is invoked on the object returned by the previous method and should itself return a new 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 1]
$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.

Interface Wrappers

In addition to the high level comobj based access to COM automation objects, TWAPI also provides object based wrappers for certain standard COM interfaces. These are provided for finer control of COM operation when the high level comobj does not provide enough flexibility. These wrapped include IUnknown, IDispatch, IDispatchEx, ITypeInfo, ITypeLib and ITypeComp. The corresponding wrapper classes are named with a Proxy suffix. For example, IUnknown is wrapped by the class IUnknownProxy.

Use of the classes requires a detailed understanding of COM programming techniques including lifetime management of objects through reference counting. Individual methods of these objects are not documented here. See the Windows SDK for details on these.

In addition to the standard methods defined by these interfaces, the proxy wrappers also implement additional helper methods that simplify working with the interfaces.

The following illustrates how these wrappers might be used:

set tlib [ITypeLibProxy_from_path  c:/windows/system32/stdole2.tlb]
set count [$tlib GetTypeInfoCount]
for {set i 0} {$i < $count} {incr i} {
    if {[$tlib GetTypeInfoType $i] == 4} {
        puts [lindex [$tlib GetDocumentation $i] 0]
    }
}
$tlib Release

The example starts off by getting a ITypeLibProxy object which wraps the ITypeLib interface for the stdole2.tlb type library. It then iterates through to print the names of dispatch interfaces in the type library using the ITypeLib methods GetTypeInfoCount, GetTypeInfoType and GetDocumentation as documented in the Windows SDK.

Note the object is released by calling Release and not its destroy method. This follows standard COM methodology. Calling the destroy method will delete the object while there might still be other references to it.

The same may be written with the @Foreach helper method as follows:

set tlib [ITypeLibProxy_from_path c:/windows/system32/stdole2.tlb]
$tlib @Foreach -type dispatch ti {
    puts [$ti @GetName]
    $ti Release
}
$tlib Release

The @Foreach method passes ITypeInfoProxy objects into the loop for every dispatch interface type entry in the library.

Using Type Libraries

Normally, TWAPI accesses COM components by looking up the method and property definitions for the object at run time via the ITypeInfo interface implemented by the object. However, some COM objects do not implement this interface and instead provide type information via a type library. An example of this is the COM support in the Windows Installer (MSI). TWAPI therefore provides facilities to extract the classes, interfaces and other data definitions associated with COM components from type libraries. Moreover, because these are extracted during development, as opposed to run time, there is a small performance gain as a side benefit as well at the cost of an additional step.

The primary command used for this purpose is the generate_code_from_typelib command. During development, this command can be used to write a file containing a Tcl script that will load the appropriate class and type definitions. The Tcl source command can then be used to load the class and type definitions at run time. Alternatively, the command can also return the script itself which can then be run via the Tcl eval command to immediately define the classes and types. Both these are illustrated by the examples below.

The following command will evaluate a script for defining type definitions for Microsoft Excel and then create a new instance of Excel.

eval [twapi::generate_code_from_typelib "c:/program files/microsoft office/office12/excel.exe"]
set xl [excel::Application new]
$xl Visible 1

In the example, the namespace excel is created based on the internal name of the library, not the file name though they happen to be the same. Within the namespace, classes such as Application, Worksheet, are defined corresponding to various COM objects. Invoking new on these classes will create instances of a COM automation object just like in the comobj command and can be used the same way. This however assumes that the COM component has been registered with the system.

In addition, the above will also define arrays within the namespace corresponding to the enums defined in the type library. For example, excel::XlRgbColor will contain the values mapping rgb color names. Similarly, constant variable definitions within a module will be contained within an array of that name.

Instead of evaling the returned script, we could also have saved it to a file using the -output option. This file could then be shipped with the application and read using the Tcl source command to recreate the definitions.

generate_code_from_typelib "c:/program files/microsoft office/office12/excel.exe" -output exceldefs.tcl

The following examples illustrate other options and scenarios. Note the commands do not eval the result which is just output to the screen so you can see the effect of the various options and the generated code. The stdole2.tlb type library is used as it is small enough to be viewed without clutter.

The following creates a script for all type definitions within the type library.

generate_code_from_typelib c:/windows/system32/stdole2.tlb

The next example creates a script for all type definitions within the type library, but within the ns namespace instead of the default stdole which is the internal type library name. If an empty string was specified instead of ns, the classes and enum array would be created in the current namespace.

generate_code_from_typelib c:/windows/system32/stdole2.tlb -namespace ns

Type libraries can be quite large and sometimes you need only a subset of the definitions. The following commands restrict the generated code to only define enums and a specific COM class respectively.

generate_code_from_typelib c:/windows/system32/stdole2.tlb -type enum
generate_code_from_typelib c:/windows/system32/stdole2.tlb -type coclass -name StdPicture

Declaring Component Types

When a component implements runtime type support, TWAPI can determine its type and associated properties, methods and their parameters by querying the object itself. If this is not the case, the type of the object has to be explicitly declared using the information imported from a type library. This is similar to the Dim statement in Visual Basic:

Dim msiDB as WindowsInstaller.Database

In TWAPI, the same would be written as (assuming msiDB is a variable holding a COMOBJ)

windowsinstaller::declare Database $msidb

This assumes that the type library was loaded into the windowsinstaller namespace. Note that the default namespace for a type library is the library name converted to lower case (this is a historical artifact). The other difference from the Visual Basic example is that the COM object must already exist. This is necessary since there is no way to "type" a variable in Tcl.

An alternative equivalent way to type a COMOBJ is through its -instanceof method.

$msidb -instanceof windowsinstaller::Database $msidb

See the documentation for the Windows Installer module for a more extensive example of how component type declarations might be used.

Controlling Parameter Types

Generally, TWAPI uses type information present in COM objects to detect parameter types and convert Tcl values appropriately. However, there are two circumstances where TWAPI has to guess the parameter type. The first case is when the COM object does not provide type information. The second case is when the parameter type is defined as a VARIANT which is a union that may be instantiated as one of several types. The COM object method may change its behaviour depending on the concret type of the passed parameter.

In languages like Visual Basic, the type of the passed parameter can be deduced because the language itself is typed. In Tcl, where "Everything Is A String", this is not possible. To deal with this situation, the application can use the tclcast command to appropriately force the passed value to a specific type. So for example, to force the passed parameter to be treated as a boolean, and not an integer, the application could call a method as follows:

$obj Visible [tclcast boolean 1]

The commands vt_empty and vt_null are convenience commands that return variants corresponding to VT_EMPTY and VT_NULL respectively.

Sometimes the COM component may not provide type information or mark a parameter as a generic VARIANT and yet expect a specific type. In such cases, even casting may not be sufficient to correctly pass parameters in the expected format. As a last resort to deal with such cases, TWAPI allows definition of prototypes for methods and properties for a COM component through the define_dispatch_prototypes command.

In the above example, instead of using a cast, a prototype for the method could be defined instead:

define_dispatch_prototypes guid {func 19 int Visible([in] bool bval)}

where guid is the GUID for the COM component and 19 is its DISPID (roughly, the index into the dispatch table). Note this requires some detailed knowledge of the COM component, like the GUID and the DISPID values for the member methods and properties.

Output Parameters

Some COM components return values in output parameters instead of, or in addition to, the method return value. The corresponding argument should be the name of the Tcl variable where the output value should be stored. If the parameter is both an input and an output parameter, the value of the variable is passed to the method. For pure output parameters, the variable value is not used and the variable need not even exist before the method call is made. When the method returns, the variable will contain the returned value as a raw COM VARIANT. Use the variant_value command to retrieve the value and variant_type to retrieve its type. When the component does not provide type information as discussed in the previous section, the outvar command can be used to indicate the passed string is the name of a variable in which to store an output parameter value. This is similar to the use of the tclcast command discussed above.

Security

When accessing COM components that are remote or run locally in a separate process, the transport connection is secured based on configuration specified by both the client and the server. These settings, termed the security blanket, are negotiated between the two and include the authentication service provider, the authentication level, the impersonation level, and identity. Clients can specify their requirements using the com_security_blanket command and retrieve a security blanket for a COM automation proxy with the -securityblanket option. Process-wide settings can be specified with the com_initialize_security command. For the server side, refer to COM server documentation.

Commands

clsid_to_progid CLSID
Returns the PROGID for a given CLSID. For example,
(tclsh) 53 % clsid_to_progid "{0002DF01-0000-0000-C000-000000000046}"
InternetExplorer.Application.1
com_initialize_security ?options?
Sets process-wide defaults for security blanket negotiation. The specified option values are used as defaults for COM access. This command can be called only once per process and must be called before any other COM command; otherwise an error is raised. If COM access is done before this command is called, it is implicitly called with defaults configured in the system registry for either the component or the system. The following options may be specified:
-appid The AppID to use to configure security. Cannot be used together with the -secd option.
-authenticationlevel AUTHLEVEL Specifies the authentication settings for securing the transport connection. AUTHLEVEL must be one of none, connect, call, packet, packetintegrity or privacy.
-authenticationservice AUTHPROVIDERNAME Specifies the service provider to use for authenticating connections. AUTHPROVIDERNAME must be one of none, negotiate, ntlm, schannel, or kerberos.
-cloaking CLOAK Specifies how identity should be cloaked when credentials are not specified. CLOAK may be one of none in which case the credentials in the process token are used, static in which case the thread token at the time of the first call is used for subsequent calls until another call to com_security_blanket, or dynamic in which the token used is the thread token at the time of each call. Only used for the client side.
-impersonationlevel IMPERSONATIONLEVEL Specified the level at which the server is allowed to impersonate the client. IMPERSONATIONLEVEL must be one of anonymous, identify, impersonate or delegate.
-secd SECD A security descriptor that controls client access to the component. Used for the server side only. Cannot be used with the -appid option.
Refer to the Windows SDK for a description of the various option values.
com_make_credentials USERNAME PASSWORD DOMAIN
Returns a descriptor containing credentials to be used for authenticating with a remote COM server. This is an alias for the make_logon_identity command.
com_security_blanket ?options?
Returns a security blanket descriptor based on the specified options. The following options may be specified to control the settings in the security blanket:
-authenticationlevel AUTHLEVEL Specifies the authentication settings for securing the transport connection. AUTHLEVEL must be one of none, connect, call, packet, packetintegrity or privacy.
-authenticationservice AUTHPROVIDERNAME Specifies the service provider to use for authenticating connections. AUTHPROVIDERNAME must be one of none, negotiate, ntlm, schannel, or kerberos.
-cloaking CLOAK Specifies how identity should be cloaked when credentials are not specified. CLOAK may be one of none in which case the credentials in the process token are used, static in which case the thread token at the time of the first call is used for subsequent calls until another call to com_security_blanket, or dynamic in which the token used is the thread token at the time of each call.
-credentials CREDENTIALS Specifies the credentials to be specified by the client for authenticating to the server. If specified and non-empty, these should be constructed using com_make_credentials. If CREDENTIALS is specified as an empty list, the credentials of the current thread token, or process token if thread token is not present, are used. If the option is not specified, the blanket indicates that the existing credentials are to be kept.
-impersonationlevel IMPERSONATIONLEVEL Specified the level at which the server is allowed to impersonate the client. IMPERSONATIONLEVEL must be one of anonymous, identify, impersonate or delegate.
-serviceprincipal NAME Specifies the server principal name. If unspecified, existing principal name is kept.
Refer to the Windows SDK for a description of the various option values. Unspecified options default to the defaults negotiated by the system either based on a prior call to com_initialize_security or configured system-wide defaults.
comobj PROGID_OR_CLSID ?options?
Creates a COM object and returns a proxy object 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.
-active If true, the returned object is attached to an existing COM instance instead of creating a new one. If no instances are running, an error is generated. Other options are ignored if this option is specified.
-authenticationlevel AUTHLEVEL Sets the authentication level for the security blanket for the connection used for activating a remote object. See com_security_blanket for details.
-authenticationservice AUTHSVC Sets the authentication service provider for the connection used for activating a remote object. See com_security_blanket for details.
-credentials CREDENTIALS Specifies the credentials to be specified by the client for authenticating to the server. These should be constructed using com_make_credentials.
-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.
-impersonationlevel LEVEL Sets the impersonation level for the security blanket for the connection used for activating a remote object. See com_security_blanket for details.
-interface IDISPATCHINTERFACE By default, the command will bind to the object's IDispatch interface. If the object is known to support the IDispatchEx interface as well, this option may be used to specify that should be used instead. IDISPATCHINTERFACE must be IDispatch or IDispatchEx.
-lcid LCID Specifies the locale to use for the COM object. Generally, LCID should be 0 (LOCALE_NEUTRAL, default), 0x400 (LOCALE_USER_DEFAULT) or 0x800 (LOCALE_SYSTEM_DEFAULT). The behaviour of some applications may depend on this setting. For example, with LCID 0, Excel will export CSV files using a comma separator while with LCID 0x400, it will use the separator symbol defined in the user's regional settings.
-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.
-securityblanket BLANKET The security blanket to use when invoking methods on a remote COM server. Note this is separate from the security blanket used for activation based on options like -credentials, -authenticationlevel etc. If unspecified but -credentials is specified, defaults to those same credentials.
-serviceprincipal NAME Specifies the server principal name for a remote component.
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. Trailing parameters with default values need not be specified.
COMOBJ -callnamedargs METHOD ?parametername parameter...?
Calls the specified COM object method with the given parameters and returns the result if any. The parameters are specified as an alternating list of the parameter names and the corresponding parameter values. The order of specification is not important and parameter names are not case sensitive. Any parameters that are not specified must have default values.
COMOBJ -default
Returns the default property of the COM object.
COMOBJ -destroy
Destroys the COM object, removing any bindings and releasing resources.
COMOBJ -dispid NAME
Returns the DISPID for a property or name. This is useful when manually defining prototypes using define_dispatch_prototypes.
COMOBJ -get PROPERTY ?parameter ...?
Returns the value of the specified property. Optional parameters may be specified if the property is an indexed property.
COMOBJ -instanceof TYPENAME
Declares the specified object be an instance of the specified type identified by TYPENAME. TYPENAME may be the name of an interface or a coclass generated by importing type library information. This is useful when type information for the object has to be obtained through its type library because the object itself does not support the ITypeInfo interface. See Declaring Component Types for more.
COMOBJ -interface ADDREF
Returns the internal IDispatch pointer. Used for debugging purposes. If ADDREF is true (default), the interface reference count is incremented and caller must at some point call twapi::IUknown_Release on the returned interface pointer to release the interface. If ADDREF is false, caller must not release the interface itself.
COMOBJ -isnull
Returns true if the object is a NULL COM object, false otherwise. This corresponds to a NULL IDispatch pointer that might be returned in some COM operations, for example, to indicate the end of a collection.
COMOBJ -iterate ?-cleanup? 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). Alternatively, the -cleanup option may be specified in which case it is automatically destroyed on each iteration (even on break and continue) and must not be explicitly destroyed.

Like the Tcl iteration commands, -iterate always returns the empty string.

See COM Collections for an example.
COMOBJ -lcid ?LCID?
If not arguments are specified, returns the locale id used by the object. If an argument is specified, it must be a Windows LCID. Generally, LCID should be 0 (LOCALE_NEUTRAL, default), 0x400 (LOCALE_USER_DEFAULT) or 0x800 (LOCALE_SYSTEM_DEFAULT).
COMOBJ -print
Prints to stdout the methods and properties of the object. Used for debugging.
COMOBJ -securityblanket ?BLANKET?
If BLANKET is not specified, returns the security blanket in use for the remote object. If BLANKET is specified, it must be a security blanket as returned by the com_security_blanket command. In that case, it is set as the new security blanket. Note that COM does not support security blankets for in-process components.
COMOBJ -set PROPERTY VALUE ?VALUE ...?
Sets the value of the specified property. Additional optional parameters may be specified if supported by the underlying COM object.
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.
comobj? COMOBJ
Returns 1 if the COMOBJ refers to a COMOBJ object and 0 otherwise.
comobj_destroy ?COMOBJ...?
Called to invoke the -destroy method on one or more COM wrapper object. Errors generated when destroying an object are ignored and the command continues to destroy remaining objects.
comobj_idispatch IDISPATCH ?ADDREF? ?LCID?
Returns a COM wrapper object for the specified IDispatch or IDispatchEx interface. If ADDREF is false (default), caller must hold a reference (count) to IDISPATCH. If ADDREF is true, the command will increment the reference count for IDISPATCH. In both cases, IDISPATCH will will be released by the COM wrapper object when it is destroyed. If caller wants to use IDISPATCH for its own purpose, it must do an additional IUnknown_AddRef itself to ensure the interface is not released when the returned COM wrapper instance is destroyed. LCID specifies the locale to use when invoking methods. Defaults to 0 (LOCALE_NEUTRAL).
comobj_instances
Returns the list of existing COM proxy objects created through the comobj command.
comobj_object DISPLAYNAME ?-interface IDispatch|IDispatchEx?
Creates a COM object identified by its display name DISPLAYNAME and returns a proxy object that can be used to access it. See comobj for more details.

By default, the command will bind to the object's IDispatch interface. If the object is known to support the IDispatchEx interface as well, the -interface option may be used to specify that should be used instead.
define_dispatch_prototypes IID PROTOTYPES
Explicitly defines the prototype (call signature) for one or more methods or properties of a COM component. IID is the interface identifier for the dispatch interface of the COM component. PROTOTYPES contains one or more prototype definitions, each of which has the following form
MEMBERTYPE DISPID RETTYPE NAME (PARAMS)
. Note PROTOTYPES is a text string, not a Tcl list. NAME is the name of the method or property. MEMBERTYPE is one of func, propget, or propput depending on whether the prototype is for a function (method), a property get operation or a property put operation. Note all three may be defined for a single name. DISPID is the dispatch index for the method or property in the component's dispatch table. This can generally be obtained from either the type library or the component's IDL definition. RETTYPE is the type of the return value (see below). PARAMS is a comma separated sequence of parameter definitions. A parameter definition has the form
?PARAMATTR? PARAMTYPE ?PARAMNAME?
The parameter name PARAMNAME is optional but all parameters must be named or none must be named. The parameter attributes PARAMATTR are also optional. If specified, it is enclosed in [] and is a list of zero or more of in, out, inout and optional which indicate whether the parameter is a input parameter, an output parameter, or both, and whether it is optional. If no attributes are specified, they default to in.

PARAMTYPE, like RETTYPE, specifies the type of the parameter. It consists of a base type optionally followed by [] indicating an array of the base type, followed optionally by * indicating a pointer. The base type may be one of bool, bstr, cy, date, decimal, i1, i2, i4, r4, r8, idispatch, iunknown, ui1, ui2, ui4, variant or void.
define_dispatch_prototypes [name_to_iid ITwapiTest] {
    func 1 bstr GetBstr(int index, bstr[] strings, [out optional] int *lengthPtr)
    propget 2 int IntegerProp()
    propput 3 void IntegerProp(int)
}
generate_code_from_typelib PATH ?options?
Generates Tcl code to access enums, interfaces and COM classes defined within a type library. PATH specifies the type library path. The following options may be specified with the command.
-name ITEMNAME Normally the command processes all items of the specfied type. If this option is specified, the generated script only contains definitions for the specified ITEMNAME.
-namespace NAMESPACE By default, the enum values and classes are defined within a namespace corresponding to the library name, converted to lower case. This option may be specified to use a different namespace instead. NAMESPACE may also be specified as an empty string in which case the script will be run in the context of the namespace it is evaluated in.
-output SCRIPTPATH The command normally returns the generated script. If this option is specified, the generated script is written out to the specified file. SCRIPTPATH may also be specified as stdout in which case it is written out to standard output.
-type TYPE Normally, the generated script processes definitions of all types. If this option is specified, only definitions of that type are processed. TYPE must be one of enum, coclass, interface or module.
See Using Type Libraries for more details about the generated code and examples.
get_typelib_path_from_guid GUID MAJOR MINOR ?-lcid LCID?
Returns the path to the type library identified by GUID that is registered with the system. MAJOR and MINOR specify the version of the libary. An optional LCID may also be specified.
iid_to_name IID
Returns the name for the interface identifier IID (a GUID).
ITypeLibProxy_from_path PATH ?-registration REGOPT?
Reads a type library from the file at PATH and returns an ITypeLibProxy object for it. The type library is also optionally registered in the system registry. If -registration is not specified or specified as none, the type library is not registered. If REGOPT is register, the type library is registered. If REGOPT is default, the system's default rules for registration are followed.

The returned ITypeLibProxy object must be freed when done by calling its Release method.
ITypeLibProxy_from_guid GUID MAJOR MINOR ?-lcid LCID?
Returns an ITypeLibProxy object for a type library identified by GUID that is registered with the system. MAJOR and MINOR specify the version of the libary. An optional LCID may also be specified.

The returned ITypeLibProxy object must be freed when done by calling its Release method.
name_to_iid INTERFACENAME
Returns the unique interface identifier (IID) for the specified interface name, for example IDispatch.
outvar VARNAME
Used to indicate that a passed parameter to a COM method is the name of a variable in which to store an output parameter value. This is useful when type information is not available for a COM object.
progid_to_clsid PROGID
Returns the CLSID for a given PROGID. For example,
(wish) 51 % progid_to_clsid InternetExplorer.Application
{0002DF01-0000-0000-C000-000000000046}
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.
unregister_typelib GUID MAJOR MINOR ?-lcid LCID?
Unregisters the type library identified by GUID with version MAJOR.MINOR from the system registry. An LCID may be optionally specified.
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.
variant_value VARIANT RAW ADDREF LCID
Converts a COM VARIANT as might be returned as an output parameter from a COM method to a Tcl value. COM VARIANTs are tagged structures. This command returns the value field of the structure. RAW and ADDREF only affect the case where the VARIANT contains an interface pointer. If RAW is false, automation (IDispatch) interface pointers are returned as comobj objects and IUnknown interface pointers are returned as proxy objects. If true, they are returned as raw pointer values. If ADDREF is true, the reference count for the interface is incremented before it is returned. LCID specifies an LCID (0 if language neutral) and is used when any locale-specific conversions need to be performed.
variant_type VARIANT
Returns the type tag of a COM VARIANT as might be returned as an output parameter from a COM method.
vt_empty
The return value from this command should be passed when a COM method parameter value should be a variant of type VT_EMPTY.
vt_null
The return value from this command should be passed when a COM method parameter value should be a variant of type VT_NULL.

COPYRIGHT

Copyright © 2006-2016 Ashok P. Nadkarni

Tcl Windows API 4.5.2