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

C#外部代码运行时编译报错:找不到动态生成程序集文件

问题诊断与修复方案

问题根源

  1. 磁盘临时文件引发的加载异常
    你将options.GenerateInMemory设为false,这会让编译器把编译后的程序集写入磁盘临时文件。但这类临时文件的生命周期不受控——可能被系统后台自动清理,或者因权限问题无法访问,所以每次报错的文件名都不固定。

  2. 参数替换未加引号,直接导致编译失败
    传递的字符串参数(比如"AAAA")直接替换占位符后,生成的代码会变成string strPar1 = AAAA;,编译器会把AAAA识别为未定义变量,直接编译失败。后续尝试加载未成功生成的程序集时,就会抛出“找不到文件”的错误(本质是没有有效程序集可加载)。

  3. 未检查编译错误
    代码中没有判断编译是否成功,不管编译结果如何都直接执行反射操作,会引发连锁异常。

修复后的完整代码

public static string CreateCSharpFunction(string strCode, string strPar1 = null, string strPar2 = null)
{
    // 使用独特占位符,避免替换时出现冲突
    var finalCode = @"
    using System;
    public class Function
    {
      public string Execute() // 避免用Main,这是程序入口方法,易引发混淆
      { 
        string strPar1 = {{strPar1}};
        string strPar2 = {{strPar2}};
        {{userCode}}
      }
     }";

    // 替换参数时添加双引号,并转义字符串内的引号
    finalCode = finalCode.Replace("{{strPar1}}", strPar1 != null ? $"\"{EscapeQuotes(strPar1)}\"" : "string.Empty");
    finalCode = finalCode.Replace("{{strPar2}}", strPar2 != null ? $"\"{EscapeQuotes(strPar2)}\"" : "string.Empty");
    finalCode = finalCode.Replace("{{userCode}}", strCode);

    var options = new CompilerParameters();
    options.GenerateExecutable = false;
    options.GenerateInMemory = true; // 改为内存生成,彻底绕开磁盘文件问题
    options.ReferencedAssemblies.Add("System.dll"); // 添加必要程序集引用,保证基础类型可用

    var provider = new CSharpCodeProvider();
    var compileResult = provider.CompileAssemblyFromSource(options, finalCode);

    // 先检查编译错误,有错误直接抛出详细信息
    if (compileResult.Errors.HasErrors)
    {
        var errorMsg = string.Join("\n", compileResult.Errors.Cast<CompilerError>().Select(e => $"[{e.ErrorNumber}] {e.ErrorText}"));
        throw new InvalidOperationException($"编译失败:\n{errorMsg}");
    }

    var type = compileResult.CompiledAssembly.GetType("Function");
    var instance = Activator.CreateInstance(type);

    var method = type.GetMethod("Execute");
    var result = method.Invoke(instance, null);

    return result?.ToString() ?? string.Empty;
}

// 辅助方法:转义字符串中的双引号,避免破坏代码结构
private static string EscapeQuotes(string input)
{
    return input?.Replace("\"", "\\\"") ?? string.Empty;
}

关键修复点说明

  • 内存生成程序集:将GenerateInMemory设为true,编译后的程序集直接存在内存中,无需写入磁盘,彻底解决文件找不到的问题。
  • 参数正确转义:用EscapeQuotes处理参数内的双引号,替换时为参数包裹双引号,保证生成的代码语法合法,不会出现未定义变量的错误。
  • 添加必要引用:加入using System;并引用System.dll,确保string、string.Empty等基础类型和成员能正常使用。
  • 编译错误检查:编译完成后先判断是否有错误,有错直接抛出详细信息,方便调试。
  • 方法重命名:把Main改为Execute,避免与程序入口方法冲突。

调用示例

// 从外部文件读取的代码示例
var strCode = @"
string strResult = strPar1 + ""ABC"";
return strResult;";

var result = Helper.CreateCSharpFunction(strCode, "AAAA");
// 输出结果:AAAAABC

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 11:23:16