The Component Object Model (COM) is a technology developed by Microsoft to enable Windows interprocess communication and dynamic object creation. COM Objects are language independent and can be implemented in any development language which has a compiler that can compile the approriate code, such as C++.
Typical examples of compiled code are:
- DLL (Dynamic Linking Library)
- OCX (ActiveX control)
- TLB (Type Libraries)
- EXE (Executables)
The access to the funtionality of a COM Object takes place through an interface, which allows the functions offered by the COM Object.
Using the “REGSVR32.EXE” Tool the most common binaries such as DLL and OCX can be registered. Thereby new class IDs are created in the registry database that refer to the relevant binary file. Thus, their functions can now be used on Windows and programs access the class IDs to perform required functions.
Examples registering compiled codes:
In case of DLL/OCX
To register a DLL or OCX, use regsvr32.exe as follows:
- Select Start -> Run
- In the dialog box, type the following:
Regsvr32 <full path of DLL or OCX to be registered>
For example, “regsvr32 C:\Windows\System32\msaatext.dll” would register the library named msaatext.
If successful, you’ll see the message:
Why not all DLL’s can be registered
A DLL needs to be specifically written to be used with the regsvr32
command to register.
The DLL must implement DllRegisterServer and DllUnregisterServer, which contain the logic that is necessary to add or delete the required registry entries for the COM component. RegSvr32 finds the entry point to these functions, and calls them appropriately.
If the DLL was not written to be used with regsvr32
then the conventional entry point will not be found, and you get an error message.
In case of TLB
To register a type library, use regtlib.exe.
- Select Start -> Run
- In the dialog box, type the following
Regtlib <full path to the type library>
For example, “regtlib C:\Program Files\MyApp\MyTypeLib.tlb” would register the library MyTypeLib.
If successful, a dialog box similar to the one shown for the DLL will appear.
In case of EXE
To register an EXE:
- Select Start -> Run
- In the dialog box, type the following:
<Full path of the EXE file> /RegServer
For example, “C:\Program Files\myAPP\MyEXE.exe /RegServer” will register the Executable MyExe.exe.
Different Types of registration Keys
Below you find some registry keys in relation with com components and its explanations.
CLSID
A CLSID (class identifier) is a globally unique identifier that identifies a COM class object. The CLSID is a 128-bit number, spelled in hexadecimal format, within a pair of braces.
One of the following values must exist to instruct the system where to find the component:
HKEY_CLASSES_ROOT\CLSID\<CLSID> (default) = <human-readable class name>
HKEY_CLASSES_ROOT\CLSID\<CLSID>\LocalServer = <full path to 16-bit file>
HKEY_CLASSES_ROOT\CLSID\<CLSID>\LocalServer32 = <full path to 32-bit file>
HKEY_CLASSES_ROOT\CLSID\<CLSID>\InprocServer = <full path to 16-bit file>
HKEY_CLASSES_ROOT\CLSID\<CLSID>\InprocServer32 = <full path to 32-bit file>
On 64-bit Windows, 64- and 32-bit in-process servers uses the InprocServer32 entry.
Other optional values include:
HKEY_CLASSES_ROOT\CLSID\<CLSID>\DefaultIcon = <path to file, icon index #>
HKEY_CLASSES_ROOT\CLSID\<CLSID>\Insertable
HKEY_CLASSES_ROOT\CLSID\<CLSID>\Interface
HKEY_CLASSES_ROOT\CLSID\<CLSID>\ProgID = <ProgID>
ProgID
The ProgID (programmatic identifier), is a Registry entry that can be associated with a CLSID. The format of a ProgID is <Vendor>.<Component>.<Version>, separated by periods and with no spaces, as in Word.Document.6. Like the CLSID, the ProgID identifies a class, but with less precision. The ProgID is stored under the following registry key:
HKEY_CLASSES_ROOT\<ProgID>
HKEY_CLASSES_ROOT\<ProgID>\(default) = <human-readable component name>
HKEY_CLASSES_ROOT\<ProgID>\CLSID(default) = <CLSID>
There are also version-independent program ID’s with the format <Program>.<Component>, as follows:
HKEY_CLASSES_ROOT\<Versionless-ProgID>
HKEY_CLASSES_ROOT\<Versionless-ProgID>\CLSID = <CLSID>
HKEY_CLASSES_ROOT\<Versionless-ProgID>\CurVer = <ProgID>
Interface
COM uses the word interface in a sense different from that typically used in Visual C++ programming. A C++ interface refers to all of the functions that a class supports and that clients of an object can call to interact with it. A COM interface refers to a predefined group of related functions that a COM class implements, but a specific interface does not necessarily represent all the functions that the class supports.
If the component needs to register an interface, it requires the following syntax:
HKEY_CLASSES_ROOT\Interface\<IID>
HKEY_CLASSES_ROOT\Interface<IID>\BaseInterface
HKEY_CLASSES_ROOT\Interface\<IID>NumMethods
HKEY_CLASSES_ROOT\Interface\<IID>\ProxyStubCLSID or ProxyStubCLSID32 = <CLSID>
TypeLib
Type libraries are files that explicitly describe some or all of the contents of components. This includes information about the methods, properties, constants, and other members exposed by the component. The following Registry keys are also set in this case:
HKEY_CLASSES_ROOT\Interface\<IID>\TypeLib\(default) = <TypeLib>
HKEY_CLASSES_ROOT\TypeLib\<TypeLib>\<#.#>\<#>\<Platform>\(default) = <path to .TLB file>
notes:
If your typelib isn’t locale-specific, you can specify 0 for the <LCID>.
<Platform> can be win32, win64 or win16 depending on the platform of the binary.
AppID
The AppID concept was introduced as part of the security support in COM. The AppID essentially represents a process that is shared by multiple CLSIDs. All objects in this process share the same default security settings.
DCOM provides mechanisms to externally configure security settings for objects and clients. In the current implementations of DCOM all security policies are enforced at the process level. All objects in a process share the same security policies, unless they programmatically override them. To match this process-wide security configuration, DCOM introduces the concept of an AppID.
AppIDs group the configuration options for one or more DCOM objects into one centralized location in the registry. COM objects hosted by the same executable must map into the same AppID. In-process COM objects that are run in a surrogate process can be forced into the same process by assigning the same AppID to their CLSID entries.
The AppID is a string which looks like a filename, e.g. “MYAPP.EXE”.
HKEY_CLASSES_ROOT\AppID\<AppID>
HKEY_CLASSES_ROOT\AppID\<AppID>\AppID = <AppID>
HKEY_CLASSES_ROOT\AppID\<AppID>\DllSurrogate or DllSurrogateExecutable = <path to file>
HKEY_CLASSES_ROOT\AppID\<AppID>\LocalService and ServiceParameters
Registering COM Component in a MSI
Windows Installer Best Practices does not recommend using the SelfReg and TypeLib table to register a COM Component.
Instead use the registry table to add the COM registration information.
To get the registration information use any “Registry Capturing tool” like RegShot to capture the registry keys. The captured registry keys should be imported into the registry table in the MSI.
The AdminStudio Software Packaging Tool contains a “Component Wizard” which automatically extracts the necessary informations and implements into the installation.
The Future of COM Components
The trend is increasingly towards .NET Framework.
The .NET Framework provides bi-directional interoperability with COM, which enables COM-based applications to use .NET components and .NET applications to use COM components.
Good to know that .NET relies on COM+ for its enterprise features. At least for the time being these technologies are complimentary. And COM is one of the core technologies that is not going away any time soon either, although from the client’s perspective, there will be more and more .NET managed APIs exposed over time, which will provide developer with a choice of interfaces.