The strange case of System.UnauthorizedAccessException when registering a Visual Studio add-in for COM Interop

Today I received a bug report for a new customer of my MZ-Tools add-in for Visual Studio (who purchased directly the product without trying the trial version) and the first thing that he encountered when running the setup was:

System.UnauthorizedAccessException: Access to the registry key ‘HKEY_CLASSES_ROOTComponent Categories{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}’ is denied.

(alas, not the most wonderful first impression about a just purchased product, but…)

He was administrator and had disabled the antivirus and other things to no avail.

The exception was thrown from RegAssemblyVSNET200X.exe, a small utility that my setup uses to register the .NET add-in DLL for COM Interop, which basically checks that some required DLLs exist on the machine and then calls System.Runtime.InteropServices.RegistrationServices.RegisterAssembly to register the assembly for COM/ Interop (the same that you can do with the regasm.exe utility of the .NET Framework).

The only reference to this problem that I found with Google was:

http://www.dotnet247.com/247reference/msgs/54/273059.aspx

That shows that a call to EnsureManagedCategoryExists is made. When you register an assembly for COM Interop, a registry entry is created like this:

HKEY_CLASSES_ROOT
   CLSID
      <Your GUID>
         Implemented Categories
            {62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}

And after creating that registry entry, the .NET Framework calls EnsureManagedCategoryExists to ensure that the implemented category, well, actually exists. Using Reflector for .NET to decompile that method I got:

Private Sub EnsureManagedCategoryExists()
   Using key As RegistryKey = Registry.ClassesRoot.CreateSubKey("Component Categories")
      Using key2 As RegistryKey = key.CreateSubKey("{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}")
         key2.SetValue("0", ".NET Category")
      End Using
   End Using
End Sub

And somehow even if you are administrator the CreateSubKey method can fail if the user doesn’t have proper permissions.

While I was investigating all this, the customer was smart enough to find this KB article explaining the problem and solution:

FIX: “Access to the Registry Key Denied” Error Message When You Register .NET Assembly for COM Interop
http://support.microsoft.com/kb/327507

The article states that it is a permissions problem (even if you are an administrator) although it does not clarify how permissions can become different on several machines (for most admins, COM Interop registration works fine). It states too that the problem was fixed in .NET Framework 1.1, which means that it should happen only with .NET Framework 1.0 (Visual Studio .NET 2002), but the customer was using MZ-Tools for Visual Studio .NET 2003, 2005 and 2008, so there is something missing here and in fact, as fas as I can tell, the logic and the decompiled EnsureManagedCategoryExists method is virtually the same for the three .NET Framework versions.

Anyway I hope this post helps to solve this problem if you ever encounter it.