COM servers

Commands for COM servers

SYNOPSIS

package require twapi_com
com_query_client_blanket
comserver_factory CLSID MEMBER_MAP CREATE_COMMAND ?FACTORYNAME?
install_coclass PROGID CLSID VERSION PATH ?options?
install_coclass_script PROGID CLSID VERSION SCRIPTPATH ?options?
resume_factories
start_factories ?CMDPREFIX?
suspend_factories
uninstall_coclass PROGID ?-scope SCOPE? ?-keepappid?

DESCRIPTION

This module provides commands for implementing COM clients and servers in Tcl. For writing COM clients, see the COM client module. TWAPI's COM server support enables writing COM components in Tcl that can be accessed by any COM client that can access COM automation components through the IDispatch interface.

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.

Overview

COM components may be implemented as DLL's which run inside the client process, termed in-process, or as separate processes, termed as localserver or out-of-process. TWAPI only supports the implementation of the latter type of component.

Information about COM components is stored in the Windows registry including the DLL or executable in which it is implemented. When a client attempts to create a COM object that is implemented as an out-of-process component, the Windows Service Control Manager (SCM) looks up executable command line for the passed CLSID in the registry and starts up a new process if there is not one already running that can service the request. The new process registers class factories with the SCM for each type of component implemented by the process (a single executable may house more than one component classes). The appropriate class factory is then invoked to create an object which is then returned to the client.

Implementing a COM component thus involves:

  • Writing the Tcl code that provides the functionality of the component(s)
  • Installing the component by registering its class with the Service Control Manager (SCM).
  • Registering the component class factory objects with the SCM when the process is started
  • Cleanly shutting down when so notified by the SCM.

Note that implementing a component using TWAPI does not require you to write an IDL file or generate a COM type library.

Implementing component functionality

The core functionality can be implemented by any Tcl command, with optional prefix arguments, that takes some action or returns a result based on a method or property name and their parameters that are passed as additional arguments. Thus it may be implemented by a TclOO object, a namespace ensemble or even a simple proc with a switch statement.

Installing a COM class

Installing a COM class involves creating the appropriate entries in the Windows registry as documented in the Windows SDK. Although these entries may be created by any means such as through a

.rgs

file, TWAPI provides the install_coclass and install_coclass_script commands for the purpose. Once installed, the executable will be started by the SCM whenever a client creates an object of the class.

When a COM class is no longer required, it can be uninstalled by calling uninstall_coclass.

Registering a class factory

When the executable containing a component begins execution, it must register factories for the classes it implements. These are invoked by the SCM to create objects belonging to a class.

The comserver_factory creates a new factory for a component class. This returns a Tcl command object. Registering the class factory with SCM is done by invoking the register method on this class.

Activating COM factories

When a factory is registered, it is in suspended mode where it does not respond to requests for object creation. The command start_factories activates all factories in the process. They are then invoked whenever a client instantiates a new object. Method calls are passed on to the class implementation and return values are passed back to the client.

For this to work, the application must be running the Tcl event loop as COM uses Windows messages to dispatch client calls to the implementing server.

Shutting down

When the process is no longer used by the SCM and there are no running COM objects resident in it, it is notified as described in the documentation for start_factories. It must then clean up by calling the destroy method on the class factory command objects returned by the comserver_factory method. The process may continue running beyond this point but the factories must be destroyed regardless.

Security

The interaction between a COM client and server is covered by a security blanket that governs authentication, impersonation, authorization and other security parameters. This security blanket is negotiated at the time the connection is established between the client and the server. The security parameters associated with the connection from a particular client can be retrieved with the com_query_client_blanket call.

Commands

com_query_client_blanket
Retrieves the security blanket parameters associated with the client whose request the server is currently executing. The returned value is a dictionary with the keys shown in the table below.
-authenticationlevel The authentication level on the connections, such as packetintegrity, privacy etc.
-authenticationservice The name of the authentication service, such as negotiate, ntlm etc.
-authorizationservice The name of the authorization service, such as dce.
-clientprincipal The client principal name.
-cloaking One of the value none, static or dynamic indicating the type of client identity cloaking that is in effect.
-serverprincipal The server principal name.
comserver_factory CLSID MEMBER_MAP CREATE_COMMAND ?FACTORYNAME?
Creates a COM component factory that will be used by COM clients to create objects of the COM class identified by CLSID. MEMBER_MAP is a dictionary mapping integer DISPID values to the method and property names for the class. CREATE_COMMAND is a command prefix that is to be invoked in the global namespace to create new objects when requested by COM clients. Note these objects do not have to be TclOO objects but any command form that can be invoked by appending the appropriate method name from MEMBER_MAP and arguments passed by the client. For example, a suitably implemented namespace ensemble would do as well.

The return value is a factory command object with two methods, neither of which take arguments. The register method should be used to register the factory with the system's Service Control Manager (SCM) so that it can invoked to create new objects on a client's request. The registration is only activated after the application calls run_comservers. The other method is destroy which should be called when the factory is to be unregistered with the SCM. This must be called before the application exits.

Other methods of the command object are intended for internal use and should not be directly invoked.
install_coclass PROGID CLSID VERSION PATH ?options?
Installs the specified coclass on a system so it can be invoked by COM clients. The following options may be specified with the command:
-appid APPID Specifies the GUID to use as the AppID for the component. Defaults to CLSID.
-appname APPNAME Specifies a human readable application name to associate with the AppID.
-inproc Specifies that the coclass is to be installed as an in-process component. PATH is the path to a DLL implementing the component.
-name NAME Specifies a human readable coclass name to associate with the class.
-outproc Specifies that the coclass is to be installed as an out-of-process component. PATH is the path to an executable implementing the component.
-params PARAMS Specifies PARAMS as additional command line parameters to be passed to the component. Only valid for out-of-process and service components and ignored otherwise.
-scope SCOPE If SCOPE is user (default), the component is installed only for the current user. If SCOPE is system it is installed for the entire system.
-service Specifies that the coclass is to be installed as an service. PATH is the name of the Windows service that implements the component. When a client attempts to access the component, the SCM will start the service PATH. Note that the service itself must have been installed previously.
install_coclass_script PROGID CLSID VERSION SCRIPTPATH ?options?
This is a wrapper around install_coclass which installs a Tcl script implementing a COM class. It locates a suitable wish.exe executable from the same directory as the current executable and installs it as an out-proc COM component. The SCRIPTPATH is passed to it as an argument.

All options are passed through to install_coclass.
resume_factories
Activates all COM factories in the process so that they can respond to client requests.
start_factories ?CMDPREFIX?
Activates all COM factories in the process so that they can respond to client requests. If no arguments are specified, the command will not return as long as there are COM servers active. It will run the Tcl event loop servicing requests until all clients have disconnected. If CMDPREFIX is specified, the command returns right away after activating the COM factories. In this case, the caller is responsible for running the event loop so that client requests can be processed. CMDPREFIX is a command prefix that will be called when all clients have disconnected and it is safe to exit.
suspend_factories
Temporarily suspends all COM factories in the process. They will not respond to requests for creating objects until they are reactivated with resume_factories.
uninstall_coclass PROGID ?-scope SCOPE? ?-keepappid?
Uninstalls the specified component from the system. SCOPE may be user (default) or system as described in install_coclass. Any AppID associated with the class is also uninstalled unless the option -keepappid is specified.

COPYRIGHT

Copyright © 2014-2016 Ashok P. Nadkarni

Tcl Windows API 4.4.0