The programming concept utilised by Windows is called the “Microsoft Component Object Model” or more commonly, just COM. The term COM is an umbrella term that encompasses the OLE, OLE Automation, ActiveX, COM+ and DCOM technologies. Regardless of the terms, all you need to know is that Windows programs have lots of registry keys that link to a physical file& the specifics of how this is done is normally based on COM.
From a packaging perspective, all we need to remember about class is that APPID, Class and ProgID registry entries are all related to code stored physically in a DLL or OCX. For a modern 32 bit application to work properly APPID, Class and ProgID entries need to be grouped with the resource file they represent in a single component. If this “set” of information has an element missing, there is a high chance that the application will not work properly.
Microsoft TreeView Control 6.0 (SP4)
Below is an example of Microsoft’s TreeView Control.
When a developer wishes to use the functionality of this control, they would be presented with a dialog similar to the one above. Notice that the control is linked to the file “C:\WINDOWS\system32\MSCOMCTL.OCX”.
A TreeView control allows Expandable representation of directories
When a developer uses this control, a window within their application will display a “tree” view of the file system because the code for the object TreeView is present and available as a result of MSCOMCTL.OCX being installed on the workstation that the application is being run.
If the file MSCOMCTL.OCX was not present on the workstation when the developer’s application was being run, there would be no ability for the machine to create a TreeView list. For an application to work correctly it also needs all of the “linked” or associated registry keys that are part of COM for the application to find the right physical file in the first place.
The next couple of pages briefly touch on what these Registry keys are… as an Application Packager you don’t need to properly understand what key does but you should have a general idea of how they all group around a particular file (that actually holds code).
Class
The highest level or grouping to do with our Component code is a Component Class. This is going to be the primary way that Windows will track the code available within our support file (MSCOMCTL.OCX ). Class represents a unique object name that will probably have a number of different methods of accessing it.
- Class is always represented as a 16 character identifier (GUID).
In this example, The COM Class for “Microsoft Tree View Control 6.0 (SP4) ” is {C74190B6-8589-11D1-B16A-00C0F0283628}.
In the Registry of a machine where this component is correctly installed, we would expect to find this “Class ID” written under the Registry section “HKEY_CLASSES_ROOT\CLSID”. The Class ID will directly link a physical file location to the Class GUID that is used by applications. This physical file will be the “server” as it will respond to code requests.
This section of the Registry is represented in the table below.
CLSID |
|||||
|
{C74190B6-8589-11D1-B16A-00C0F0283628} |
||||
|
|
InprocServer32 |
|||
|
|
|
(Default) |
REG_SZ |
C:\WINDOWS\system32\MSCOMCTL.OCX |
|
|
|
ThreadingModel |
REG_SZ |
Apartment |
|
|
ProgID |
|||
|
|
|
(Default) |
REG_SZ |
MSComctlLib.TreeCtrl.2 |
|
|
TypeLib |
|||
|
|
|
(Default) |
REG_SZ |
{831FDD16-0C5C-11D2-A9FC-0000F8754DA1} |
Server “Type”
On a standard, 32 bit Windows installation, the path to the server will be written to the Registry as either “InProcServer32” or “LocalServer32”. Different types of Server are represented by the different entries:
Inprocserver32 represents a DLL or OCX based server
LocalServer32 represents an EXE based server
Threading Model
Our component may well be run in the same process as the client using it or it may be run in a different process. Processes that run one after another (single threading) or many at the same time (multithreading) are identified by their Threading Model. This execution context is called an “Apartment”
The Threading Model for an Apartment will be either;
Apartment (Single Threaded Apartments)
Free (Multi Threaded Apartments)
Both (A process that can be single or multi-threaded)
ProgID
A “Programmatic Identifier” maps to a ClassID and is a human friendly way of referring to an object class.
TypeLib
TypeLib (or a Type Library) contains information about the interfaces available via a particular Class Object. Typelib is often queried by development tools as a pointer to see what objects are installed.
COM Execution Context
Windows can tell how to call an object directly from the Class ID section of the Registry. When that object is called, there may be additional properties or characteristics about how it’s expected to be run. There may even be instances where the same COM Server could be run by the operating system in different ways depending on how it’s called.
Interface
The method of controlling how code is run (i.e. its context) and its ability to interface with other objects is recorded under the “Interface” section for Class in the registry.
This section directly relates to:
HKEY_CLASSES_ROOT\Interface\ “Class GUID”
If we look directly at this section of the Registry for our example object
Interface |
|||||
{C74190B4-8589-11D1-B16A-00C0F0283628} – (This links to the Class keys) |
|
||||
|
ProxyStubClsid |
|
|||
|
|
(Default) |
REG_SZ |
{00020424-0000-0000-C000-000000000046} |
|
|
ProxyStubClsid32 |
|
|||
|
|
(Default) |
REG_SZ |
{00020424-0000-0000-C000-000000000046} |
|
|
TypeLib |
|
|||
|
|
(Default) |
REG_SZ |
{831FDD16-0C5C-11D2-A9FC-0000F8754DA1} |
|
|
|
Version |
REG_SZ |
1.0 |
|
Linking COM Registry Keys
The table below shows the registry keys that are all linked to provide the functionality of Microsoft’s Treeview Contol 6.0. Notice how the information under Class, Interface and Typelib keys are all linked to eachother. Don’t forget, the purpose of all of these keys is to actually point to code contained in a physical file.
CLSID |
|
||||||||||
|
{C74190B6-8589-11D1-B16A-00C0F0283628} |
||||||||||
|
|
InprocServer32 |
|||||||||
|
|
|
(Default) |
REG_SZ |
C:\WINDOWS\system32\MSCOMCTL.OCX |
||||||
|
|
|
ThreadingModel |
REG_SZ |
Apartment |
||||||
|
|
ProgID |
|||||||||
|
|
|
(Default) |
REG_SZ |
MSComctlLib.TreeCtrl |
||||||
|
|
TypeLib |
|||||||||
|
|
|
(Default) |
REG_SZ |
{831FDD16-0C5C-11D2-A9FC-0000F8754DA1} |
||||||
Interface |
|
||||||||||
|
{C74190B4-8589-11D1-B16A-00C0F0283628} |
||||||||||
|
|
ProxyStubClsid |
|||||||||
|
|
|
(Default) |
REG_SZ |
{00020424-0000-0000-C000-000000000046} |
||||||
|
|
ProxyStubClsid32 |
|||||||||
|
|
|
(Default) |
REG_SZ |
{00020424-0000-0000-C000-000000000046} |
||||||
|
|
TypeLib |
|||||||||
|
|
|
(Default) |
REG_SZ |
{831FDD16-0C5C-11D2-A9FC-0000F8754DA1} |
||||||
|
|
|
Version |
REG_SZ |
1.0 |
||||||
TypeLib |
|
||||||||||
|
{831FDD16-0C5C-11D2-A9FC-0000F8754DA1} |
||||||||||
|
|
2.0 |
|||||||||
|
|
|
(Default) |
REG_SZ |
Microsoft Windows Common Controls 6.0 (SP6) |
||||||
|
|
|
0 |
||||||||
|
|
|
|
win32 |
|||||||
|
|
|
|
|
(Default) |
REG_SZ |
C:\WINDOWS\system32\MSCOMCTL.OCX |
||||
MSComctlLib.TreeCtrl |
|
||||||||||
|
CLSID |
||||||||||
|
|
(Default) |
REG_SZ |
{C74190B6-8589-11D1-B16A-00C0F0283628} |
|||||||
All registry keys may be viewed under HKEY_CLASSES_ROOT
Orphaned COM
The previous section went deeply into the different sections of the registry that written to as a result of properly registering a COM object.
The functions of the registry are concerned with the ability of applications to be able to “hook” or fish code out of physical files.
Understanding COM can be very difficult but it is the most important factor to grasp in being an effective packager. The following analogy may help in understanding the concept further.
Motor vehicle details will be recorded in a number of databases. A motor vehicle requires a number plate, a Warrant of Fitness and probably insurance. All three registers will point to a particular vehicle but they are all likely to contain information as to the actual license plate with in all three databases.
Vehicle Registration (License) -->
Warrant of Fitness -->
Insurance -->
The important “thing” in this scenario is the actual car while the different registers maintain slightly different information that point to the vehicle.
COM registration within Windows is exactly the same. Instead of trying to track a car, Windows uses it’s registry to link to an actual file that contains code.
CLSID -->
TypeLib -->
ProgID -->
When code is referenced from a particular file an application may refer to that code by using a Class ID, Prog ID or Typelib. These methods are interlinked registers within the Registry but the important “thing” that is being tracked is the actual code itself.
Application Packagers must ensure that the COM registry entries associated with a particular file (i.e. pointers to a file) stay grouped with that file.
When COM based registry keys end up in separate components to the file they are supposed to refer to we call them Orphaned. Orphaned COM is the biggest problem for MSI packaging as it allows the code needed by applications and the pointers that point to it to get cross linked or completely broken.
It can be a time consuming process but professionalism requires all Orphaned COM to be properly resolved. Failure to do so will break DLL counting rules and will most likely cause applications to fail when an MSI package is removed.
- Log in to post comments