TWAPI COM support

APN TWAPI includes COM client support. 4.1a6 adds server support.

Example:

    package require twapi
    set ie [twapi::comobj InternetExplorer.Application] ;# Start Internet Explorer
    $ie Visible 1  ;# Make it visible
    $ie Navigate http://www.google.com ;# Go to Google
    after 10000 ;# Wait so you can see it
    $ie Quit    ;# exit IE
    $ie -destroy  ;# Destroy the COM object

For more examples, see

PO's CAWT package layers application specific COM support for many Windows applications (Office, Google Earth, Matlab etc.)


Other packages that support COM are optcl and tcom. Differences from these are:

  • Lack of automatic lifetime management. COM objects have to be explicitly released as in optcl whereas tcom automatically manages reference counts.

On the other hand, there are a couple of features in TWAPI that tcom and optcl do not have which improve usability.

  • A generalized -with option that allows navigation through a method path without having to manually create intermediate objects
  • Support for dynamically created COM properties and methods (IDispatchEx interface] using standard syntax for accessing properties (see example below)
  • Generation of TclOO classes for COM objects based on type library information
  • Ability to explicitly specify prototypes for methods when type library information is not available.
  • Support for 64-bit Windows

Here is the direct TWAPI WMI translation of the tcom example from Matthias Hoffmann - Tcl-Code-Snippets - tcom & wmi - Examples

  proc readPopUps {} {
    set res {}
    set wmi [twapi::_wmi]
    set wql {select * from Win32_NTLogEvent where LogFile='System' and \
                 EventType='3'    and \
                 SourceName='Application Popup'}
    set svcs [$wmi ExecQuery $wql]

    # Iterate all records
    $svcs -iterate instance {
        set propSet [$instance Properties_]
        # only the property (object) 'Message' is of interest here
        set msg [$propSet Item Message]
        set msgVal [$msg Value]
        lappend res $msgVal
        $msg -destroy
        $propSet -destroy
    }

    $svcs -destroy
    $wmi -destroy
    return $res
  }

And here is the same example, in slightly more succint form making use of -with and dynamic properties.

  proc readPopUps2  {} {
    set res [list ]
    set wmi [twapi::_wmi]
    $wmi -with {
        {ExecQuery "select * from Win32_NTLogEvent where LogFile='System' and EventType='3' and SourceName='Application Popup'"}
    } -iterate event {
        lappend res [$event Message]
        $event -destroy
    }
    $wmi -destroy
    return $res
  }

Note there is no need to explicitly retrieve the _Properties collection and index it to access dynamic properties (like Message). They can be directly accessed like static properties, just as in Visual Basic. Secondly, there is no need to create a temporary object (svcs in the first example). The -with allows you to implicitly follow a path through a object hierarchy.