views:

367

answers:

1

I have an IE BHO (a toolbar) written in C#/.NET 2.0 using COM Interop. I'm using Visual Studio 2005 to generate an MSI installer for my toolbar using the Setup Project.

In my assembly, I have COM register/unregister methods using the ComRegisterFunctionAttribute, which set the registry keys that give IE some key information about my toolbar (like the name of the toolbar). In my setup project, I register my dll for COM using the vsdrpCOMRelativePath property (see code below).

When I install with the MSI, the toolbar functions properly, but I have one nagging problem: When I start IE and go to select my toolbar, it appears in the list of valid toolbars, but it has the fully qualified class name: "MyToolbar.IEHelperToolbar" instead of a normal name: "IEHelperToolbar"

It seems as though the MSI generated by the setup project is not calling the custom registration methods I've defined in my assembly. I've come to this conclusion because if I use regasm.exe to register the dll, IE displays the correct name.

Should I be using a different registration setting in my setup project, or should I follow the approach in this post:, or I should I just give up on the VS2005 setup project and go to something like WIX, or am I way off base?

Here are my register/unregister functions:

 /// <summary>
/// Called when derived class is registered as a COM server.
/// </summary>
[ComRegisterFunctionAttribute]
public static void Register(Type t)
{
    string guid = t.GUID.ToString("B");

    RegistryKey rkClass = Registry.ClassesRoot.CreateSubKey(@"CLSID\" + guid);
    RegistryKey rkCat = rkClass.CreateSubKey("Implemented Categories");

    ToolbarAttribute[] boa = (ToolbarAttribute[])t.GetCustomAttributes(
        typeof(ToolbarAttribute),
        false);

    string name = t.Name;
    string help = t.Name;
    ToolbarStyle style = 0;
    if (boa.Length == 1)
    {
        if (boa[0].Name != null)
            name = boa[0].Name;

        if (boa[0].HelpText != null)
            help = boa[0].HelpText;

        style = boa[0].Style;
    }

    rkClass.SetValue(null, name);
    rkClass.SetValue("MenuText", name);
    rkClass.SetValue("HelpText", help);

    if (0 != (style & ToolbarStyle.Vertical))
        rkCat.CreateSubKey("{00021493-0000-0000-C000-000000000046}");

    if (0 != (style & ToolbarStyle.Horizontal))
        rkCat.CreateSubKey("{00021494-0000-0000-C000-000000000046}");

    if (0 != (style & ToolbarStyle.TaskbarToolBar))
        rkCat.CreateSubKey("{00021492-0000-0000-C000-000000000046}");

    if (0 != (style & ToolbarStyle.ExplorerToolbar))
        Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Toolbar").SetValue(guid, name);

}

/// <summary>
/// Called when derived class is unregistered as a COM server.
/// </summary>
[ComUnregisterFunctionAttribute]
public static void Unregister(Type t)
{
    string guid = t.GUID.ToString("B");
    ToolbarAttribute[] boa = (ToolbarAttribute[])t.GetCustomAttributes(
        typeof(ToolbarAttribute),
        false);

    ToolbarStyle style = 0;
    if (boa.Length == 1) style = boa[0].Style;

    if (0 != (style & ToolbarStyle.ExplorerToolbar))
        Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Toolbar").DeleteValue(guid, false);

    Registry.ClassesRoot.CreateSubKey(@"CLSID").DeleteSubKeyTree(guid);
}
+1  A: 

The installer packaged with VS2005 is very broken for projects that require COM registration. I spent about 2 days trying to get it to work properly a few years back, then discovered the free NSIS installer and never turned back.

Have a look at:

http://nsis.sourceforge.net/Main_Page

Eric J.