c++ - 如何停止 CLR 托管?
问题描述
我有注入到目标程序的 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);
解决方案
我不太确定我是否完全理解您的问题或特定环境,但我还是冒险回答。YMMV。
您不能完全卸载 CLR。
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 注入“任何”其他进程可能一开始就不是一个好主意。
推荐阅读
- php - Laravel Horizon - 不同守卫的大门
- jquery - 迭代数组>填充选择框>从函数返回选择框作为html
- python - 如何在使用 vscode 调试时执行设置 python 虚拟环境的 shell 脚本(我需要对 launch.json 进行哪些更改)
- c# - 发送发布请求多部分表单数据。来自某些 Microsoft 服务的错误“超出行长限制 100”
- python - 在 Windows 中使用 pyinstaller 将 .py 文件转换为 .exe 时出错
- python - 将请求正文中的文件 POST 到 API
- vcpkg - 如何将 osgearth 与 vcpkg 一起使用
- asp.net-core - 将框架和本机运行时文件移动到子文件夹中
- php - 如何在使用 sed commnad 将文本转换为 csv 时将重复列显示为单独的列?
- angular - Angular 8 使用 Ivy 创建自定义元素