سؤال

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...

هل كانت مفيدة؟

المحلول

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();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top