0

I need to register a .NET COM dll from a C++ program that is using it. For .NET versions older then .NET 4 this is explained in How to run regasm.exe from a C++ program?. Following is the minimal code (no checks) that provides the path to an older version of the CLR.

CComBSTR mscoreeName("mscoree.dll");
HINSTANCE hMscoree = CoLoadLibrary(mscoreeName, FALSE);
typedef HRESULT (WINAPI *LPFNGETCORSYSDIR)(LPWSTR, DWORD, DWORD*);
LPFNGETCORSYSDIR lpfunc = (LPFNGETCORSYSDIR)GetProcAddress(hMscoree,_T("GetCORSystemDirectory"));

DWORD bufferSize = 256;
DWORD bufferUsed;
LPWSTR pwzBuffer = new WCHAR[bufferSize];
(*lpfunc)(pwzBuffer, bufferSize, &bufferUsed);

However since I use .NET 4 the method GetCORSystemDirectory is superseded by the ICLRRuntimeInfo::GetRuntimeDirectory which is not an entry point in mscoree.dll (checked with depends). According the documentation on MSDN the method is included as a resource in MSCorEE.dll.

Question is how to get access to this method from C++?

Besides that I'm wondering if there is no easier way...

Community
  • 1
  • 1
Lorenz
  • 165
  • 1
  • 1
  • 10
  • you want use regasm to register a .NET DLL? – Matt Apr 18 '14 at 13:45
  • It was not the right way to do it in the first place, pretty doubtful that you appropriate dealt with a [ComRegisterFunction] or the need to register the type library. Using COM is a hard requirement to do it right, you probably avoided it intentionally. As long as you have to go there, write a little C# library which is [ComVisible] that uses RegistrationServices.RegisterAssembly() and call *that* one from your C++ program. – Hans Passant Apr 18 '14 at 13:52
  • The ComVisible .NET DLL is a replacment of a COM component written in VB6. These components are used in a framework written in C++. The suggestion of Hans to write ComVisible .NET component to register it is as solution but maybe I should rephrase the question to "How to register a ComVisible .NET DLL in C++. – Lorenz Apr 18 '14 at 14:13

1 Answers1

0

The problem with the way of working in the question is in finding the correct location of RegAsm. Thanks to the comment of Hans Passant to use RegistrationService.RegisterAssembly I changed the ClassLibrary into a self-registering executable.

static void Main(string[] args)
{
    if (args.Length != 1)
    {
        ShowHelpMessage();
        return;
    }

    if (args[0].CompareTo("/register") == 0)
    {
        Assembly currAssembly = Assembly.GetExecutingAssembly();
        var rs = new RegistrationServices();
        if (rs.RegisterAssembly(currAssembly, AssemblyRegistrationFlags.SetCodeBase))
        {
            Console.WriteLine("Succesfully registered " + currAssembly.GetName());                    
        } else
        {
            Console.WriteLine("Failed to register " + currAssembly.GetName());                                        
        }
        return;
    }

    if (args[0].CompareTo("/remove") == 0)
    {
        Assembly currAssembly = Assembly.GetExecutingAssembly();
        var rs = new RegistrationServices();
        if (rs.UnregisterAssembly(currAssembly))
        {
            Console.WriteLine("Succesfully removed " + currAssembly.GetName());
        }
        else
        {
            Console.WriteLine("Failed to remove " + currAssembly.GetName());
        }
        return;
    }

    ShowHelpMessage();
}
Lorenz
  • 165
  • 1
  • 1
  • 10