Every component class requires a unique CLSID to identify it. The registry entries under that CLSID identify the server module for that component. In Chapter 2, we saw the basic use of the CLSID in the registry, which took the following form:
\
CLSID
{42754580-16b7-11ce-80eb-00aa003d7352} = Acme Component 3.0
The ProgID and VersionIndependentProgID entries are omitted here because they are not particularly relevant to this discussion. In any case, COM requires that you include at least one of the following entries as an additional subkey of the hexadecimal CLSID string:
The value of each entry must be the full pathnames of the DLL or EXE in question; this way, you do not depend on those modules being in the system path. COM enforces this requirement and will fail to load a server if the full pathname is not listed. For that reason, a component's installation program usually updates these values after the exact installation location is known. In any case, any single server DLL or EXE can support as many CLSIDs as it wants because COM provides the CLSID to a class factory when asking it to instantiate an object. This means that the same DLL or EXE pathname can appear under as many CLSIDs in the registry as desired.
These keys can appear in any combination if multiple server modules for the same CLSID exist. When multiple server entries exist, COM will attempt to use them in the order InprocServer32, InprocHandler32, LocalServer32 unless the client has specified a restriction to only in-process servers or only local servers. For a number of reasons, you might choose to supply both an in-process server and a local server. The most important of these is that a client can then choose which server it would like to use. An in-process server is faster, but if that server crashes it can potentially take down the entire client process. On the other hand, a local server, having its own process space, can crash without any ill effect on the client, thereby making the relationship more secure and robust, but slower.
A useful combination is to register a handler together with a local server. InprocHandler32 appearing by itself implies that only a partial implementation of a component is available. In many situations, this is perfectly reasonable because partial implementation provides some basic capabilities to clients without requiring the full server. We'll see an example of this in OLE Documents later, in Chapter 19. One use for this combination is to freely distribute a handler as a sort of crippled component that encourages customers to purchase the full component.
If you use REG files to create registry entries, be very, very careful about extra spaces preceding pathnames in that file: extra spaces make different values. In other words, an entry such as:
\...\...\InprocServer32 = c:\inole\chap05\dkoala1\dkoala1.dll
is different from:
\...\...\InprocServer32 = c:\inole\chap05\dkoala1\dkoala1.dll
where an extra space precedes "c:\inole…" This is the sort of bug you can stare at for hours, and your brain will simply refuse to see it.