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

从原生Win32应用调用含Roslyn引用的.NET DLL加载失败求助

解决原生Win32通过C++/CLR调用依赖Roslyn的.NET5 DLL的程序集加载问题

针对你遇到的System.IO.FileNotFoundException(无法加载Microsoft.CodeAnalysis系列程序集)问题,核心原因是原生Win32 EXE作为CLR宿主时,默认的程序集探测路径仅指向原生EXE所在目录,而Roslyn的依赖未被CLR正确识别。以下是具体解决方案:

1. 在C++/CLR桥接层手动配置程序集探测路径

在CLRLibCaller的初始化逻辑中,强制将DynCodeDll所在目录添加到CLR的私有程序集搜索路径,同时注册AssemblyResolve事件作为兜底,确保所有依赖能被正确加载:

#using <System.dll>
#using <System.IO.dll>
using namespace System;
using namespace System::Reflection;
using namespace System::IO;

void InitAssemblySearchPath() {
    // 加载DynCodeDll并获取其所在目录
    Assembly^ dynCodeAssembly = Assembly::LoadFrom(L"DynCodeDll.dll");
    String^ dynCodeDir = Path::GetDirectoryName(dynCodeAssembly->Location);

    // 设置CLR私有程序集搜索路径
    AppDomain::CurrentDomain->PrivateBinPath = dynCodeDir;

    // 注册AssemblyResolve事件,兜底加载未找到的依赖
    AppDomain::CurrentDomain->AssemblyResolve += gcnew ResolveEventHandler(
        [dynCodeDir](Object^ sender, ResolveEventArgs^ args) -> Assembly^ {
            String^ assemblyShortName = gcnew AssemblyName(args->Name)->Name;
            String^ assemblyPath = Path::Combine(dynCodeDir, assemblyShortName + L".dll");
            
            if (File::Exists(assemblyPath)) {
                return Assembly::LoadFrom(assemblyPath);
            }
            return nullptr;
        }
    );
}

注意:必须在调用DynCodeDll的任何功能之前调用InitAssemblySearchPath函数。

2. 正确部署DynCodeDll的所有依赖

使用.NET5的dotnet publish命令发布DynCodeDll,确保所有Roslyn相关依赖(如Microsoft.CodeAnalysis.CSharp.dll、Microsoft.CodeAnalysis.dll等)被完整导出:

dotnet publish DynCodeDll.csproj -c Release -f net5.0 --self-contained false

将发布目录下的所有文件(包括DynCodeDll.dll、runtimeconfig.json及所有依赖DLL)复制到NativeExeCaller的输出目录,或者在InitAssemblySearchPath中指定该发布目录为搜索路径。

3. 检查C++/CLR项目的配置兼容性

  • 确保CLRLibCaller项目的公共语言运行时支持设置为/clr:netcore(项目属性→配置属性→C/C++→所有选项→公共语言运行时支持),目标.NET版本与DynCodeDll一致(.NET5)。
  • 确认CLRLibCaller的输出目录与NativeExeCaller的输出目录一致,或通过项目依赖设置自动复制CLRLibCaller到原生EXE目录。

4. 利用AssemblyLoadContext精准加载依赖

如果上述方法仍有问题,可使用AssemblyLoadContext加载DynCodeDll,指定其依赖目录和配置文件:

#using <System.Runtime.Loader.dll>
using namespace System::Runtime::Loader;

Assembly^ LoadDynCodeDll() {
    String^ dynCodeDir = L"[DynCodeDll的发布目录路径]";
    String^ configPath = Path::Combine(dynCodeDir, L"DynCodeDll.runtimeconfig.json");
    
    AssemblyLoadContext^ alc = AssemblyLoadContext::LoadFromAssemblyPath(
        Path::Combine(dynCodeDir, L"DynCodeDll.dll"),
        configPath
    );
    return alc->LoadFromAssemblyName(gcnew AssemblyName(L"DynCodeDll"));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 03:13:00