Search code examples
c#visual-c++com-interopregasm

Registering a COM Interop DLL > Class not registered


I am familiar with the process of how to register a COM Interop. Eg:

enter image description here

As long as I am running Visual Studio using Administrator elevation this C# COM DLL will compile and register for interop. The TLB is created. So there are issues with that process. And I have no issues (technically speaking) with using the DLL at runtime from my application.

Here is the problem:

  • My primary Visual C++ installer rightly registers these DLLs with regasm. So, after install, I can run my installed application without issue.
  • But, if I try to run the application from within Visual Studio (and the results are the same if I try with / without elevation) it fails with:

Class not registered

I understand the issue I think. The installer does the registering:

2024-04-11 15:01:09.874   -- Run entry --
2024-04-11 15:01:09.874   Run as: Current user
2024-04-11 15:01:09.874   Type: Exec
2024-04-11 15:01:09.889   Filename: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe
2024-04-11 15:01:09.889   Parameters: MyFile_x64.dll /codebase
2024-04-11 15:01:10.108   Process exit code: 0

But Visual Studios version of this DLL, held in my source codes Release folder, is not registered. And thus that path to that DLL is not found in the registry. So I am getting this error:

Class not registered

Since it is a DLL, and it is being used from a Visual C++ application, I import he TLB file like this:

#ifdef _WIN64
#import "..\\..\\xxx\\yyy\\bin\\x64\\Release\\MyFile.tlb" raw_interfaces_only named_guids
#else
#import "..\\..\\xxx\\yyy\\bin\\x86\\Release\\MyFile.tlb" raw_interfaces_only named_guids
#endif

Don't know if that helps. Using the DLL is as expected:

void CFoo::Init()
{
    throw_if_fail(m_pInterface.CreateInstance(__uuidof(XXX::XXXClass)));
}

What step am I missing here for both my installed versions and my compiling versions work?


I can verify that:

  1. The two respective DLL builds are configured to registry the COM interop setting. So create the TLBs that we need.

  2. My installer is registering its respective DLLs correctly:

Filename: "{dotnet40}\regasm.exe"; \
    Parameters: "MSAToolsLibrary_x86.dll /codebase"; \
    WorkingDir: "{app}\MSAToolsLibrary"; \
    Flags: runhidden; \
    Check: not Is64BitInstallMode

Filename: "{dotnet40}\regasm.exe"; \
    Parameters: "MSAToolsGMailLibrary_x86.dll /codebase"; \
    WorkingDir: "{app}\MSAToolsGMailLibrary"; \
    Flags: runhidden; \
    Check: not Is64BitInstallMode

Filename: "{dotnet4064}\regasm.exe"; \
    Parameters: "MSAToolsLibrary_x64.dll /codebase";  \
    WorkingDir: "{app}\MSAToolsLibrary"; \
    Flags: runhidden; \
    Check: Is64BitInstallMode

Filename: "{dotnet4064}\regasm.exe"; \
    Parameters: "MSAToolsGMailLibrary_x64.dll /codebase"; \
    WorkingDir: "{app}\MSAToolsGMailLibrary"; \
    Flags: runhidden; Check: Is64BitInstallMode

They are registering with the correct regasm and I can run either application after installation. This much I know.

I just can't get my local main application to run.


If I manually copy my x64 release exe to the installed C PF folder ad click it - it works.


Solution

  • The problem seemed to be because I had added a post build event to my DLL project to copy the dlls files to a sub folder of my source C++ project. So:

    1. Empty the PostBuildEvent contents.
    2. Delete the obsolete folders in my C++ projects output folders.
    3. Rebuild everything.

    Now all is good. The DLLs appear in one of 3 places:

    1. x86 install folder.
    2. x64 install folder.
    3. local admin build folder.