shahine.com/omar/

homepage | Send mail to the author(s) contact

yet another Microsoft blogger

# Wednesday, April 28, 2004

When COM Registration fails in an MSI (vsdraCOM has no affect)

 Summary

In this weeks’ installment of I hate COM, lets talk about a frustrating problem I’ve been having (turns out I had this problem when I wrote my Media Center Front Panel Display but found a different workaround I mention below). It would be nice if there were a KB article on this topic, but there isn’t and I don’t know why.

Say you are exposing a .NET component as a COM component. Not to uncommon. I already do this in my Outlook2OneNote add-in as well as my Media Center Front Panel Display. In both these cases I am implementing a COM Interface: Extensibility.IDTExtensibility2 for Outlook2OneNote and EHLib.IMediaStatusSink for my Media Center Sink.

In Outlook2OneNote the project structure looks like

  1. Project 1 – contains the guid and COM Inteface
  2. Project 2 – inherits from a class in Project 1 and is marked for COM registration
  3. Setup – Primary Output from Project 2’s Register value is vsdraCOM

In MediaCenterSink the project structure looks like

  1. Project 1 – contains the guid and COM Inteface and marked for COM registration
  2. Project 2 – contains the code for the Sink
  3. Setup – Primary Output from Project 1’s Register value is vsdraCOM

In both cases the MSI does not register the Primary Output for COM Interop. It’s not obvious why this fails, but I spent many hours trying various things (you know how trial and error is when you don’t have an understanding for what is going on or what is broken right?). So you can imagine how frustrating this is. Even more frustrating is when this happens to you twice in the course of a few months.

Approach 1: Custom Action

Well, google had no answers for me except a bunch of other people who were saying “COM Registration during install using MSI is broken…” or “vsdraCOM doesn’t do anything…” etc. The only solution that I found was to write some code in the Primary Output project like so (you need a similar Uninstall and Rollback override as well):

public override void Install(System.Collections.IDictionary stateSaver)
{
    base.Install(stateSaver);

    try
    {
        RegistrationServices regSrv;

        // Register the assembly
        regSrv = new System.Runtime.InteropServices.RegistrationServices();

        if (!regSrv.RegisterAssembly(
            this.GetType().Assembly, AssemblyRegistrationFlags.SetCodeBase))
        {
            throw new InstallException("Failed to register componenet for COM interop");
        }
    }
    catch
    {

    }
}

And then create a Custom Action in your MSI that points to the Primary Output for Install, Uninstall and Rollback. This actually works pretty well, and I was happy with it.

Well when this problem happened for the second time just this week when I switched my Outlook2OneNote project structure from being a simple Project that had all the logic to one that inherited from another class in another project I started wondering and thinking this has to be a bug. Well using my super hero powers I tracked this problem down and found a better work around.

Additionally, I've been told that custom actions should be avoided for a number of reasons. One good reason is that if you ever use the MSI in the future to upgrade your assembly, it will fail.

Approach 2: Simple workaround for bug

Rather than adding the Primary Output of the project that needs to be registered for COM Interop, do the following:

  1. In your setup project remove the Primary output from <Project Name>.
  2. Select your setup project, right click, select Add->Assembly
  3. Navigate to the bin/Release directory of your Primary project and select your dll
  4. Select the Assembly in the setup project and set the Register value to vsdraCOM

Summary

By adding your assembly directly to the MSI and not relying on the Custom Action workaround mentioned above, you can rely on the MSI to register your component for COM Interop.

BTW – IMHO, developing .NET components and exposing them as COM components is a nasty business and one that I NO LONGER ENJOY!!! I am writing this because it’s a bit therapeutic and I hope it helps someone else who is having this problem (rather than hurl my laptop against the wall).

update: I made some corrections to this post based on some feedback from Rob Mensching.

 

Wednesday, April 28, 2004 2:19:17 PM (Pacific Daylight Time, UTC-07:00)
"developing .NET components and exposing them as COM components is a nasty business and one that I NO LONGER ENJOY!!!"

Ha! Did you ever REALLY enjoy it? ;)
Thursday, April 29, 2004 12:10:52 AM (Pacific Daylight Time, UTC-07:00)
LOL. I guess not.
Tuesday, June 29, 2004 8:36:59 AM (Pacific Daylight Time, UTC-07:00)
Hello Omar, and the rest of the bloggers...

I was using the Shared Add-in, form Extensibility Projects, template in Visual Studio .NET 2003, to create an Outlook 2003 add-in.

I used an article wrote by Andrew Troelsen named 'An Introduction to Programming Outlook 2003 using C#' as the base literature for the project.

In this article he mentioned this blog's workaround to the COM registering problem.

I used your second workaround and it seemed to work on my workstation. I then tried to install it on a different one and guess what? The setup failed to register them component. No sign of it (it should create a combo box and a button) on the UI and neither on the add-in manager.

Worst of all I am using the IDTExtensability2 interface OnStartupComplete() event, and to be shure I was catching it I even presented a Message Box to the user stating I was installing a new add-in. On the other workstation the Message Box doesn't show up, stating that either the add-in failed to install itself or it is not receiving the events info from Outlook.

Do you have any idea of what might be happening, and how I might solve this?

Thank you in advance.

Hugo

Portugal

Hugo Fonseca
Tuesday, June 29, 2004 9:39:53 AM (Pacific Daylight Time, UTC-07:00)
I found the solution to my problem in this article:

http://support.microsoft.com/default.aspx?scid=kb;en-us;302901

Thank you very much anyway,

Hugo
Hugo Fonseca
Thursday, September 09, 2004 4:07:13 PM (Pacific Daylight Time, UTC-07:00)
I too have tried the example 'An Introduction to Programming Outlook 2003 using C#' with out success. I am reading all of the articles mentioned hear but I'm still stumped. Does anyone have a working example I can use to teach myself?

Thanks,

Jason
Jason
Thursday, December 09, 2004 2:08:30 PM (Pacific Standard Time, UTC-08:00)
Just try the link Hugo mentioned, it works quite well. I even tried uninstalling the AddIn - worked fine. O.K, you have to remove the created Buttons manually and you don't see the AddIn in the AddIn Manger, but for me this example was more inspiring than 'An Introduction to Programming Outlook 2003 using C#'...
Jörg
Tuesday, August 02, 2005 5:46:59 PM (Pacific Daylight Time, UTC-07:00)
It looks like I'm more an exception to the rule, but I never had problems with COM registration of .NET components. Here is my approach, you might hate it but it is 100% reliable:
1) Run REGASM.EXE to generate a REG file containing the registry definintions.
2) Manually adapt these registry definitions to your setup mechanism of choice (INF, MSI or just stick with the old REG). Yes, I know it's a lot of work but I like to have tight control on what goes to registry during my setup part.
3) Register your assembly in GAC using the preffered method.

Done!
Monday, September 12, 2005 5:55:49 PM (Pacific Daylight Time, UTC-07:00)
I used regasm as well had had success with this.
Saturday, October 22, 2005 7:53:11 AM (Pacific Daylight Time, UTC-07:00)
I had similar problems with the Andrew W. Troelsen's article.

In my case I noticed that I getting two refernces to Office.dll. I removed the old one in the addin project (verions 7.x in my case). I also excluded the double reference in the install project by excluding the same reference.

Everything worked fine from that point on and have written several addins for Outlook with no further issues.

Cheers

Simon
Simon Rigby
Wednesday, November 21, 2007 4:18:02 AM (Pacific Standard Time, UTC-08:00)
We think we'll need to use a custom action to get Word Addins working, because of the Security Policy business. The Addin DLL needs to be explicitly granted Full Trust permission. Presumably this is to prevent non-privileged users installing and running DLLs out of their home directories, given some future system where users can only write in their home directories or the equivalent of /tmp and these users can't grant piviledges. At the moment anyone who can install can also grant so it seems to give no benefit.

It's incredibly complex and that complexity is made worse by the complexities of MSI, WiX, COM and how Word handles addins. A simpler way would have been to allow Word to only run addins that exist in a special location that only the administrator can write to - security without complexity and also the advantage that Word documents don't go round with the full local path of the Add-IN DLL coded in them! The pro graphics software I run at home works this way.

Maybe using WiX and not the Visual Studio publish wizard is asking for pain, though policy is that our code generator will generate the installer too to make it easier for developers but very hard for the installer generator developer.
Richard
Comments are closed.