COM AddIn registration at deployment time
How many times have you forgotten something you had worked hard on and promised yourself that you would not forget how you did this thing? Well, if you use VS.NET 2003, have developed a solution which utilises COM and want to deploy your solution using the stock VS.NET Installer, then article is for you!
To deploy your code, you normally just choose the Add Project Output... context menu-item of your Setup project to have your selected Project's output files (Assemblies etc) included into your Setup project. This results in your msi file containing the project output files which are then deployed to the file-system of the machine when it is run.
Sadly, because my solution requires some COM plumming to be performed at deployment time, I found that my solution did not wholly work. The files and application Registry entries were being deployed, but the COM plumbing was being skipped.
Believe me when I say that I must have learned how to resolve this issue before as I had msi files for two previous releases which worked just fine. But I just couldn't recall what I did to fix this issue!
So, determined, and armed with earlier versions of installer for my solution, I searched for the answer...
How To Register COM Objects in Visual Studio .NET 2002 http://support.microsoft.com/?id=307367
This article explains the VS.NET 2002 actions to be performed but I could not find a corresponding VS.NET 2003 article. Everything being suggested was in order in my Setup project, but still the COM registration was not being performed at deployment time.
Using Orca, I discovered that the Class and ProgID tables of the latest msi were not being populated, whereas they were populated for previous releases. This indicated something fundamental was not being performed.
What Is ORCA and How Can I Acquire It? http://support.installshield.com/kb/view.asp?articleid=Q107066
Windows Installer - Class Table http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/shortcut_table.asp
After a good few hours of trying different approaches, I googled across this article...
David Guyer [MS] (VIP) There is a known bug (in both VS 2002 and VS 2003) where Regasm fails to register properly if you are trying to register an assembly and the dependency can't be found. If you run RegAsm in the bin dir, usually the dependencies are copied locally. However, setup projects run regasm from the obj dir (for other important reasons), where the dependency is not available. In this case, setup projects will fail to register correctly. The workaround is to add the assembly to your project as a "file", right-click in the File System Editor, and select Add File, and navigate to the assembly in the bin dir. Usually that gets regasm to work and we get theproper registration information. ---David Guyer - VBQA Deployment Testing http://www.dotnet247.com/247reference/msgs/46/231535.aspx
So, armed with this new information, here's what I did:
In my Setup project (Solution Explorer window), I removed the Project Output item - all the assemblies were automatically removed ;
Using the Setup project Add File... context menu-item, I added each of the relevant assemblies from the bin\release folder of my Solution's launch project, plus the type-library file, which is created as a result of a compilation where the Project Register for COM Interop option is set to True;
I then checked that the Register property of my TLB file was set to vsdrfCOM and the corresponding assembly Register property was set to vsdraCOM;
In my Set project (Solution Explorer window), I noted that all of the assemblies (files) I just added were now listed under the Detected Dependencies folder AND directly beneath the Setup project - to overcome a Build warning duplicate files message, I had to set theExclude property to True for each file listed beneath the Detected Dependencies folder;
After selecting the Setup project's Build option the msi was created;
Using Orca, I now checked the msi Class and ProgID tables and they were now populated, as before.
After running the msi, all files were correctly deployed to the file-system and the appropriate COM registration had been performed.
Oh, deep joy!
I hope this artcile helps me to remember a hard-learned lesson and also helps anyone else suffering the same issue a speedy resolution to a nasty and not well publicised VS.NET deployment issue.
Update - I found this response to a NewsGroup post, which partly explains what happens behind the scenes when you create a VS.NET Installer.
From: Phil Wilson ([email protected]) Subject: Re: installer woes (MSI generated by VS.NET 2003) Newsgroups: microsoft.public.windows.msi Date: 2005-02-01 19:18:58 PST
If I had to make one major point about this, it's that you don't need to be in the business of writing your own registration code to make this work. If you put your assembly in an application folder and in its Properties mark it to be registered (vsdraCOM IIRC) VS will extract the registration data into the MSI file and create the right registry entries at install time. The reason this works is that VS sees the Register property and behind your back it runs regasm /codebase to create a .reg file that it imports into the MSI file. You could even think about doing this yourself if you like, just to see what happens. Use regasm /codebase on your assembly to create a .reg file and then import that file into the Registry view in the Visual Studio IDE. Some of the paths will be wrong - you might need to use [TARGETDIR]your.dll to specify the Codebase value, and the InprocServer32 will be [WindowsFolder]mscoree.dll, if I've remembered properly. -- Phil Wilson[Microsoft MVP-Windows Installer]











