COM in the Windows Installer World - Relative Paths and Side-by-Side COM Components
(Page 6 of 7 )
Side-by-side COM components are COM components that are installed without an absolute path to the server. You might have noticed that there was a vsdrfCOMRelativePath choice in the VS Register options for COMServer.dll. Perhaps you’re thinking that this is the way to install a side-by-side COM server, because a relative path is one of the requirements for a side-by-side installation. However, there is a bit more than that going on here. If you were to use this choice, install the resulting package, and look at the registration entries, you’d see that the InprocServer32 key doesn’t contain the absolute path to the server. It does indeed have just the name of the DLL: COMServer.dll. Here’s an interesting test to try: In the COMServerInst project, a test VB script (CALLCOM.VBS) displays a property from the COM object with a couple of lines of code:
set obj = CreateObject ("COMServer.MyClass")
msgbox (obj.SomeString(1) )
If you install the COM server using that vsdrfCOMRelativePath property, it doesn’t matter what folder you run this script from. You should find that it works every time, despite the thought that this simply shouldn’t be working because the InprocServer32 key entry points only to a relative path, not the complete path to the DLL. What’s happening here is that Windows Installer is getting involved at the point that the DLL needs locating. I’ve mentioned that Windows Installer keeps track of each installer component that gets installed on the system. A component has a KeyPath, located in the Component table in the package, so Windows Installer knows the installed location of every component on the system. This means Windows Installer can locate the complete path to the COM server. Knowing the product code GUID and the installer component GUID for the COM server, Windows Installer can locate the file by locating the component’s KeyPath. But how does it know these installer GUIDs? They’re encoded into that InprocServer32 data item, the descriptor that looks like a corrupted entry. You can show that this is the case by deleting that InprocServer32 descriptor entry from the Registry, after which the preceding script no longer works. Right-clicking the package, the MSI file, and choosing Repair restores the missing entry, which causes the script to start working again.
A Detour: Locating Components In Chapter 2 you built a VBScript that listed all the files in an installer package. You can extend this script to do what Windows Installer just did: Locate the component on the system by getting the component’s KeyPath. This is part of the listcomponents.vbs file supplied with the COMServerInst project. Error-handling code and opening the database package are removed from these fragments:
Sub ListComponents
Dim view, record, componid, componpath, componversion, fullmsg
fullmsg = "Product " & ProductGuid & vbcrlf
Set view = database.OpenView("SELECT `ComponentId` FROM `Component`")
view.Execute : CheckError
Do
Set record = view.Fetch : CheckError
If record Is Nothing Then Exit Do
componid = record.StringData(1)
componpath=""
componpath = installer.ComponentPath (ProductGuid,
componid)
if componpath <> "" then
componversion = installer.fileversion (componpath,
false)
fullmsg = fullmsg & componpath & " " & componversion
& vbcrlf
end if
Loop
msgbox fullmsg
End Sub
The beginning of the preceding code should look familiar from Chapter 2. This is a SQL-type query on the Component table to return ComponentID, which is the actual GUID for this installer component. Given the ProductCode GUID and the component GUID, the ComponentPath property of the installer object returns the absolute path to the component’s KeyPath. The ComponentPath property requires the ProductCode GUID as well as the com-ponent’s GUID. That’s because the same component might have been installed to any number of different locations by different products, so the owning product needs to be specified. Note that the installer object also has a FileVersion property that retrieves the version from the path to the file. If you wanted to find out the installation location of each component of an installation package, this is the general way to do so. Beware that a KeyPath can also be a Registry key, and write your code accordingly; in these cases the ComponentPath returned starts with a numeric representation of the Registry hive (such as “02” for HKLM).
The point of this exploration of relative paths was to show that Windows Installer is integrated into COM in a rather interesting way. However, to use actual side-by-side COM components you need to go a bit further.
This chapter is from The Definitive Guide to Windows Installer by Phil Wilson. (Apress, 2004, ISBN: 1590592972 ). Check it out at your favorite bookstore today. Buy this book now.
|
Next: Back to Side by Side >>
More Windows Scripting Articles
More By Apress Publishing