【问题标题】:How do I stop CLR Hosting?如何停止 CLR 托管?
【发布时间】:2020-10-21 09:04:56
【问题描述】:

我有注入目标程序的 C++ dll 并希望从中加载 C# 脚本,为此我创建了一个包装器,它从 C++ dll 获取函数并托管 clr 以加载 C# 应用程序。我正在像这样调用 CLR 托管线程,但我需要在运行时更改 C# 脚本,因此需要先卸载此脚本。我怎样才能做到这一点 ?如何从不在线程中的其他函数停止 CLR 托管?

DWORD WINAPI CreateDotNetRunTime(LPVOID lpParam)
    {
        ICLRRuntimeHost* lpRuntimeHost = NULL;
        ICLRRuntimeInfo* lpRuntimeInfo = NULL;
        ICLRMetaHost* lpMetaHost = NULL;
        FILE* file;
    
        LPWSTR AppPath = new WCHAR[_MAX_PATH];
        ::GetModuleFileNameW((HINSTANCE)&__ImageBase, AppPath, _MAX_PATH);
    
        std::wstring tempPath = AppPath;
        int index = tempPath.rfind('\\');
        tempPath.erase(index, tempPath.length() - index);
        tempPath += Assembly;
    
        fopen_s(&file, Log, "a+");
    
        HRESULT hr = CLRCreateInstance(
            CLSID_CLRMetaHost, 
            IID_ICLRMetaHost, 
            (LPVOID*)&lpMetaHost
        );
    
        if (FAILED(hr))
        {
            fprintf(file, "Failed to create CLR instance.\n");
            fflush(file);
        }
    
        hr = lpMetaHost->GetRuntime(
            L"v4.0.30319", 
            IID_PPV_ARGS(&lpRuntimeInfo)
        );
    
        if (FAILED(hr))
        {
            fprintf(file, "Getting runtime failed.\n");
            fflush(file);
    
            lpMetaHost->Release();
        }
    
        BOOL fLoadable;
        hr = lpRuntimeInfo->IsLoadable(&fLoadable);
    
        if (FAILED(hr) || !fLoadable)
        {
            fprintf(file, "Runtime can't be loaded into the process.\n");
            fflush(file);
    
            lpRuntimeInfo->Release();
            lpMetaHost->Release();
        }
    
        hr = lpRuntimeInfo->GetInterface(
            CLSID_CLRRuntimeHost, 
            IID_PPV_ARGS(&lpRuntimeHost)
        );
    
        if (FAILED(hr))
        {
            fprintf(file, "Failed to acquire CLR runtime.\n");
            fflush(file);
    
            lpRuntimeInfo->Release();
            lpMetaHost->Release();
        }
    
        hr = lpRuntimeHost->Start();
    
        if (FAILED(hr))
        {
            fprintf(file, "Failed to start CLR runtime.\n");
            fflush(file);
    
            lpRuntimeHost->Release();
            lpRuntimeInfo->Release();
            lpMetaHost->Release();
        }
    
        DWORD dwRetCode = 0;
    
        hr = lpRuntimeHost->ExecuteInDefaultAppDomain(
            (LPWSTR)tempPath.c_str(), 
            Class,
            Method, 
            Param, 
            &dwRetCode
        );
    
        if (FAILED(hr))
        {
            fprintf(file, "Unable to execute assembly.\n");
            fflush(file);
    
            lpRuntimeHost->Stop();
            lpRuntimeHost->Release();
            lpRuntimeInfo->Release();
            lpMetaHost->Release();
        }
    
        fclose(file);
    
        return 0;
    }

调用它:

CreateThread(NULL, NULL, CreateDotNetRunTime, NULL, NULL, NULL);

【问题讨论】:

    标签: c++ hosting clr


    【解决方案1】:

    我不太确定我是否完全理解您的问题或特定环境,但我还是冒昧地回答一下。 YMMV。

    您不能完全卸载 CLR。​​

    来自ICLRRuntimeHost::Stop 文档:

    This method does not release resources to the host, unload application domains,
    or destroy threads. You must terminate the process to release these resources.
    

    要完全回收CLR(主机),最好在单独的(子)进程中启动它,并通过IPC方式与它通信。您将从您的(注入的)线程开始该过程。

    此外,将一些重量级的、依赖和资源负载的东西作为 CLR 注入“任何”其他进程可能一开始就不是一个好主意。

    【讨论】:

      猜你喜欢
      • 2013-10-28
      • 2011-07-03
      • 2011-01-21
      • 2012-10-19
      • 1970-01-01
      • 2010-09-25
      • 1970-01-01
      • 1970-01-01
      • 2013-03-06
      相关资源
      最近更新 更多