如何停止 CLR 主机?

How do I stop CLR Hosting?

本文关键字:主机 CLR 何停止      更新时间:2023-10-16

我有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);

我不太确定我是否完全了解您的问题或特定环境,但我还是冒险回答。扬子晚报.

不能完全卸载 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 注入到"任何"其他进程中可能首先不是一个好主意。