Registering .Net COM DLLs without Admin rights / regasm Registering .Net COM DLLs without Admin rights / regasm vba vba

Registering .Net COM DLLs without Admin rights / regasm


Setting up the registry files

To register the components for use in 32 and 64 bit environments, we are going to need to modify the registry file we created in our test case. Open it with your favorite text editor. The entries should look something like this:

[HKEY_CLASSES_ROOT\\YourAssembly.Class]@="YourAssembly.Class"[HKEY_CLASSES_ROOT\\YourAssembly.Class\\CLSID]@="{YourClassGUID}"

Make sure that it includes "CodeBase"= entries.

Do a global find/replace:

  • Change HKEY_CLASSES_ROOT (which is aliasing to HKLM\Software\Classes)
  • To HKEY_CURRENT_USER\Software\Classes

Copy all of the registry keys (and their values, which are listed below the keys) to a second text file. In the second text file:

  • Delete all of the keys (and their related values) that do not contain \CLSID\
  • Do a global find/replace:
    • Change Classes\CLSID
    • To: Classes\Wow6432Node\CLSID

Copy all of the keys from the second text file to your original .reg file, and save it.

Remove the registration entries from HKLM by using regasm:

Regasm YourDLL.dll /unregister

Make sure things don't work

In order to make sure that our change worked (and that you're not just successful because of the registration you did with regasm originally), we need to make sure that VBA cannot create the object right now.

Open up your favorite VBA application, and add a reference to YourDLL.tlb. Create a new procedure that is something like this:

Public Sub TestYourDLL()  Dim x as AssemblyName.ClassName  Set x = New AssemblyName.ClassName  Debug.Print "Apparently this worked."End Sub

Run TestYourDLL. You should receive the error:

Run-time error '429':ActiveX component can't create object

(If you don't receive the error, your DLL is still registered.)

Save and exit your VBA application.

Making sure they work

Now, run the YourDLL.reg that you created earlier to import the entries to the registry. (If you get an "Access denied" message, you forgot to change from HKEY_CLASSES_ROOT to HKEY_CURRENT_USER\Software\Classes)

Open your VBA application again, and run TestYourDLL. You should now see "Apparently this worked." in your immediate window. Congratulations! You've registered the DLL! (If you get an "Automation error: The system cannot find the file specified"-type error, your registry file is either missing the Codebase entries, or they are not pointing to the actual location of your DLL.)

Additional steps

In my case, I'm going to be installing the DLL on a bunch of other users' computers alongside my application, so at installation time I'll update the CodeBase value to refer to the location where I'm installing the DLL, and I'll also install the registry entries through code, rather than by executing the .reg file. But, now that I know the required entries, doing that is trivial.


C White's answer is great if you can do it manually on every computer.

For automatically adding the necessary registry entries, I use the following code. It accounts for 32-bits Office on 64-bits Windows, and can be cleaned up afterwards.

Public Sub RegisterDLL(DLLPath As String)    Dim RegasmPath As String    RegasmPath = "C:\Windows\Microsoft.NET\Framework\" & Dir("C:\Windows\Microsoft.NET\Framework\v4*", vbDirectory) & "\RegAsm.exe" 'Path to RegAsm, adjust to the version of the .Net framework you're targeting    #If Win64 Then        Const Win64 = True    #Else        Const Win64 = False    #End If    Dim LibraryPath As String    LibraryPath = Left(DLLPath, Len(DLLPath) - 4)    If Dir(DLLPath) = "" Then 'Check if file exists        Err.Raise 1, Description:="Missing DLL!"        Exit Sub    End If    CreateObject("WScript.Shell").Run """" & RegasmPath & """ """ & DLLPath & """ /codebase /regfile", 0, True 'Create .reg file using RegAsm    Dim strNewRegPath As String    If Not Win64 And Environ$("ProgramW6432") <> vbNullString Then        strNewRegPath = "HKEY_CURRENT_USER\SOFTWARE\Classes\Wow6432Node" '32 bits Office on Win 64    Else        strNewRegPath = "HKEY_CURRENT_USER\SOFTWARE\Classes" 'Default registry path    End If    Dim strRegFileContent As String    Dim fileNo As Integer    fileNo = FreeFile    Open LibraryPath & ".reg" For Binary Access Read Write As #fileNo        strRegFileContent = String(LOF(fileNo), vbNullChar)        Get #fileNo, , strRegFileContent 'Read reg contents        strRegFileContent = Replace(strRegFileContent, "HKEY_CLASSES_ROOT", strNewRegPath) 'Change reg path        Put #fileNo, 1, strRegFileContent 'Overwrite, always extends so no need to truncate    Close #fileNo    CreateObject("WScript.Shell").Run "regedit.exe /s """ & LibraryPath & ".reg""", 0, True  'Merge silently into registry    Kill LibraryPath & ".reg" 'Clean up registryEnd Sub

Just use RegisterDLL "C:\Path\To\File.DLL" to automatically add the required entries.

To clean up when uninstalling, you can use the following:

Public Sub UnregisterDLL(DLLPath As String)    Dim RegasmPath As String    RegasmPath = "C:\Windows\Microsoft.NET\Framework\" & Dir("C:\Windows\Microsoft.NET\Framework\v4*", vbDirectory) & "\RegAsm.exe" 'Path to RegAsm, adjust to the version of the .Net framework you're targeting    #If Win64 Then        Const Win64 = True    #Else        Const Win64 = False    #End If    Dim LibraryPath As String    LibraryPath = Left(DLLPath, Len(DLLPath) - 4)    If Dir(DLLPath) = "" Then 'Check if file exists        Err.Raise 1, Description:="Missing DLL!"        Exit Sub    End If    CreateObject("WScript.Shell").Run """" & RegasmPath & """ """ & DLLPath & """ /codebase /regfile", 0, True 'Create .reg file using RegAsm    Dim strNewRegPath As String    If Not Win64 And Environ$("ProgramW6432") <> vbNullString Then        strNewRegPath = "HKEY_CURRENT_USER\SOFTWARE\Classes\Wow6432Node" '32 bits Office on Win 64    Else        strNewRegPath = "HKEY_CURRENT_USER\SOFTWARE\Classes" 'Default registry path    End If    Dim strRegFileContent As String    Dim fileNo As Integer    fileNo = FreeFile    Dim fileOutput As Integer    fileOutput = FreeFile + 1    Open LibraryPath & ".reg" For Input As #fileNo    Open LibraryPath & "remove.reg" For Output As #fileOutput        Line Input #fileNo, strRegFileContent 'Read reg contents        Print #fileOutput, strRegFileContent 'Copy first line blindly        Do While Not EOF(fileNo)            Line Input #fileNo, strRegFileContent 'Read reg contents            strRegFileContent = Replace(strRegFileContent, "HKEY_CLASSES_ROOT", strNewRegPath) 'Change reg path            If Left(strRegFileContent, 1) = "[" Then 'If new key                Print #fileOutput, "[-" & Mid(strRegFileContent, 2) 'Change to remove key            End If        Loop    Close #fileOutput    Close #fileNo    Kill LibraryPath & ".reg" 'Remove create file    Shell "regedit.exe /s """ & LibraryPath & "remove.reg""" 'Merge silently into registry    Kill LibraryPath & "remove.reg" 'Remove delete fileEnd Sub

These scripts require no references, and no admin access. They should generally run fast and allow for setting on application startup, and cleaning on application shutdown, if conflicts might be an issue.