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

在Roslyn中添加引用报错:FileNotFoundException无法加载程序集

Roslyn加载依赖程序集报错的解决方案

问题现象

即使通过CreateFromStream或CreateFromFile方法为Roslyn编译添加了依赖程序集的元数据引用,编译成功后加载生成的程序集时仍抛出如下错误:

FileNotFoundException: 无法加载文件或程序集'SimpleLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'。系统找不到指定的文件。

问题原因

Roslyn编译阶段仅依赖元数据引用完成语法和语义检查,但运行时CLR需要找到依赖程序集的实际文件才能加载。如果依赖程序集不在CLR的默认搜索路径中,就会触发找不到文件的异常。

解决方案

方案一:将依赖程序集放入CLR搜索路径

  • 把SimpleLibrary.dll复制到当前应用程序的输出目录(如bin/Debug/net6.0);
  • 或者将SimpleLibrary.dll所在的目录(如d:\)添加到系统PATH环境变量中;
  • 这样CLR在加载生成的程序集时,就能自动找到依赖文件。

方案二:通过AssemblyResolve事件加载内存中的依赖

如果不想复制物理文件,可以在加载生成的程序集前,注册AppDomain.CurrentDomain.AssemblyResolve事件,当CLR找不到依赖时,从内存中直接加载对应的程序集。

修改后的完整代码示例:

using System;
using System.IO;
using System.Reflection;
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

List<MetadataReference> references = new List<MetadataReference>();

// 读取依赖程序集到内存,保留字节数组供后续加载使用
byte[] libraryBytes = File.ReadAllBytes(@"d:\SimpleLibrary.dll");
using (Stream stream = new MemoryStream(libraryBytes))
{
    references.Add(MetadataReference.CreateFromStream(stream));
}

string code = @"
using SimpleLibrary;
namespace RoslynCompileSample
{
    public class Program
    {
        public bool Main()
        {
              return true;
        }
    }
}";

// 创建编译对象(原代码中缺失的关键部分)
var compilation = CSharpCompilation.Create(
    "RoslynCompileSampleAssembly",
    syntaxTrees: new[] { CSharpSyntaxTree.ParseText(code) },
    references: references,
    options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

using (var ms = new MemoryStream())
{
    try
    {
        EmitResult result = compilation.Emit(ms);
        if (result.Success)
        {
            ms.Seek(0, SeekOrigin.Begin);
            byte[] compiledAssemblyBytes = ms.ToArray();

            // 注册程序集解析事件,处理依赖加载
            AppDomain.CurrentDomain.AssemblyResolve += (sender, resolveArgs) =>
            {
                var targetAssemblyName = new AssemblyName(resolveArgs.Name);
                if (targetAssemblyName.Name.Equals("SimpleLibrary", StringComparison.OrdinalIgnoreCase))
                {
                    return Assembly.Load(libraryBytes);
                }
                return null;
            };

            // 加载生成的程序集并执行方法
            Assembly assembly = Assembly.Load(compiledAssemblyBytes);
            Type programType = assembly.GetType("RoslynCompileSample.Program");
            object instance = Activator.CreateInstance(programType);
            var methodResult = programType.InvokeMember(
                "Main",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod,
                null,
                instance,
                null);
        }
        else
        {
            // 输出编译错误信息
            foreach (var diagnostic in result.Diagnostics)
            {
                Console.WriteLine(diagnostic.ToString());
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"执行出错:{ex.ToString()}");
    }
}

注意事项

  • 如果存在多个依赖程序集,需要在AssemblyResolve事件中逐一处理每个缺失的程序集;
  • 确保保存依赖程序集字节数组的变量(如libraryBytes)在事件触发时未被回收,需保持其生命周期覆盖程序集加载阶段;
  • 原代码中缺失了CSharpCompilation对象的创建逻辑,这是Roslyn编译的核心步骤,必须补充完整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 07:35:19