You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过CLRProfiler从物理路径加载托管C# DLL而非GAC?

从物理路径加载托管DLL到CLR运行时:用CLRProfiler实现的方案

背景:当托管DLL位于GAC中时,我可以通过公钥令牌和程序集名加载,代码如下:
MetaDataAssemblyEmit->DefineAssemblyRef(pbPublicKeyOrToken, publicKeySize, assemblyName, &assemblyMetaData, NULL, 0, 0, &mdAssemblyRef);
现在我希望从物理路径而非GAC加载该DLL引用,尝试了LoadLibrary(L"C:\\Packages\\MyDotNetAssembly.dll");——这段代码已将DLL加载到进程中,但并未加载至CLR运行时。请问能否通过CLRProfiler实现此需求?

当然可以用CLRProfiler实现这个需求!首先得理清核心问题:LoadLibrary是Win32层面的API,它只会把DLL加载到进程的非托管内存空间,但CLR完全不知道这个DLL的存在,自然不会把它当作托管程序集来处理。而CLRProfiler基于CLR的Profiling API,能深度介入CLR的程序集加载流程,正好可以解决这个问题。

具体的实现思路和步骤如下:

  • 第一步:配置并启用自定义CLRProfiler
    你需要编写一个自定义的CLRProfiler DLL,实现ICorProfilerCallback3(或更高版本的接口)。然后通过环境变量(比如COR_PROFILER、COR_ENABLE_PROFILING)让目标进程加载你的Profiler,或者通过进程注入的方式完成挂载。

  • 第二步:监控程序集加载事件
    在Profiler的Initialize回调中,启用COR_PRF_MONITOR_ASSEMBLY_LOADS监控标志,这样CLR会在程序集加载的关键阶段通知你的Profiler。重点关注AssemblyLoadStarted回调——当CLR尝试加载你目标程序集(就是之前用DefineAssemblyRef指定的assemblyName)时,这个回调会触发。

  • 第三步:重定向程序集加载路径
    当AssemblyLoadStarted触发时,检查当前要加载的程序集名称、版本、公钥令牌是否和你物理路径中的DLL完全匹配。确认匹配后,调用ICorProfilerInfo3::RedirectAssembly方法,把CLR的加载请求重定向到你指定的物理路径(C:\\Packages\\MyDotNetAssembly.dll)。这个方法会告诉CLR放弃原本的GAC查找逻辑,转而从你指定的路径加载程序集。

  • 额外注意事项

    1. 确保物理路径中的DLL和GAC中的目标程序集具有完全一致的名称、版本、公钥令牌——CLR会严格验证程序集的强名称,不匹配的话加载会失败(测试环境可临时关闭强名称验证,但生产环境不建议这么做)。
    2. 无需再调用LoadLibrary,CLR在加载托管程序集时会自动把DLL加载到进程中,重复加载可能引发冲突。
    3. 你的Profiler需要足够的权限,因为要挂钩CLR的内部运行时事件,某些场景下可能需要以管理员身份运行目标进程。

这样操作后,CLR就会从你指定的物理路径加载目标托管DLL,而不是去GAC查找,完全满足你的需求。

内容的提问来源于stack exchange,提问作者anbu2388

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:20:59