title: Setup Project COM Registration
body: <p>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. </p>
  
  <p>In my assembly, I have COM register/unregister methods using the <strong>ComRegisterFunctionAttribute</strong>, 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 <strong>vsdrpCOMRelativePath</strong> property (see code below). </p>
  
  <p>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: "<em>MyToolbar.IEHelperToolbar</em>" instead of a normal name: "<em>IEHelperToolbar</em>"</p>
  
  <p>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. </p>
  
  <p>Should I be using a different registration setting in my setup project, or should I follow the approach in this <a href="https://stackoverflow.com/questions/12807/how-to-register-com-from-vs-setup-project">post</a>:, or I should I just give up on the VS2005 setup project and go to something like WIX, or am I way off base?</p>
  
  <p>Here are my register/unregister functions:</p>
  
  <pre><code> /// &lt;summary&gt;
  /// Called when derived class is registered as a COM server.
  /// &lt;/summary&gt;
  [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 &amp; ToolbarStyle.Vertical))
          rkCat.CreateSubKey("{00021493-0000-0000-C000-000000000046}");
  
      if (0 != (style &amp; ToolbarStyle.Horizontal))
          rkCat.CreateSubKey("{00021494-0000-0000-C000-000000000046}");
  
      if (0 != (style &amp; ToolbarStyle.TaskbarToolBar))
          rkCat.CreateSubKey("{00021492-0000-0000-C000-000000000046}");
  
      if (0 != (style &amp; ToolbarStyle.ExplorerToolbar))
          Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Toolbar").SetValue(guid, name);
  
  }
  
  /// &lt;summary&gt;
  /// Called when derived class is unregistered as a COM server.
  /// &lt;/summary&gt;
  [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 &amp; ToolbarStyle.ExplorerToolbar))
          Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Toolbar").DeleteValue(guid, false);
  
      Registry.ClassesRoot.CreateSubKey(@"CLSID").DeleteSubKeyTree(guid);
  }
  </code></pre>