C# 运行时编译生成的文件可以';不能删除

C# 运行时编译生成的文件可以';不能删除,c#,runtime-compilation,C#,Runtime Compilation,我有一个控制台类型的东西,它接受一行C#代码,将其封装在周围的代码中,并将其编译成程序集。然后,我从该程序集中调用该方法,输出结果,就这样 问题是,程序集需要有一个名称,以便我可以将其设置为朋友程序集,以便它可以访问非公共类。我把它命名为“控制台” 一切正常,但问题是,在一个脚本完成后,我无法运行第二个脚本,因为名为“console”的文件已存在于目录中,无法覆盖 我尝试过用Dispose方法处理所有东西。我已尝试使用file.Delete手动删除该文件。没有任何帮助 这是我使用的代码。我希望有

我有一个控制台类型的东西,它接受一行C#代码,将其封装在周围的代码中,并将其编译成程序集。然后,我从该程序集中调用该方法,输出结果,就这样

问题是,程序集需要有一个名称,以便我可以将其设置为朋友程序集,以便它可以访问非公共类。我把它命名为“控制台”

一切正常,但问题是,在一个脚本完成后,我无法运行第二个脚本,因为名为“console”的文件已存在于目录中,无法覆盖

我尝试过用Dispose方法处理所有东西。我已尝试使用file.Delete手动删除该文件。没有任何帮助

这是我使用的代码。我希望有人能帮助我

CSharpCodeProvider provider = new CSharpCodeProvider();
var param = new CompilerParameters();
param.GenerateInMemory = false;
param.GenerateExecutable = false;
param.OutputAssembly = "console";
param.ReferencedAssemblies.Add("System.dll");
param.ReferencedAssemblies.Add("System.Core.dll");
param.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
var results = provider.CompileAssemblyFromSource(param,
@"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace FireflyGL
{
class DebugConsole
{
    static void Run(StringWriter writer)
    {
        var stdOut = Console.Out;
        Console.SetOut(writer);
        " + input.Text + @"
        Console.SetOut(stdOut);
    }
}
}");
            if (results.Errors.HasErrors)
            {
                for (int i = 0; i < results.Errors.Count; ++i)
                {
                    PushText(results.Errors[i].ErrorText);
                }
            }
            else
            {
                try
                {
                    var writter = new StringWriter();
                    results.CompiledAssembly.GetType("FireflyGL.DebugConsole").GetMethod("Run", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { writter });
                    PushText(writter.ToString());
                    history.Add(input.Text);
                    currentHistory = history.Count;
                    input.Text = "";
                    writter.Dispose();
                }
                catch (Exception)
                {

                }
            }
            provider.Dispose();
            File.Delete(results.CompiledAssembly.Location);
CSharpCodeProvider provider=新的CSharpCodeProvider();
var param=新编译器参数();
param.GenerateInMemory=false;
param.GenerateExecutable=false;
param.OutputAssembly=“控制台”;
参数referencedAssemblys.Add(“System.dll”);
param.referencedAssemblys.Add(“System.Core.dll”);
param.ReferencedAssembly.Add(Assembly.GetExecutionGassembly().Location);
var results=provider.CompileAssemblyFromSource(参数,
@"
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.IO;
命名空间FireflyGL
{
类调试控制台
{
静态无效运行(StringWriter编写器)
{
var stdOut=Console.Out;
控制台。放样(编写器);
“+input.Text+@”
控制台放线(标准输出);
}
}
}");
if(results.Errors.HasErrors)
{
对于(int i=0;i
必须卸载程序集才能删除所有引用。不幸的是,你不能这样做。但是,您可以卸载,如果您在该
AppDomain
中引用程序集,它也将被卸载


如果您不关心创建内存泄漏,也可以为程序集创建唯一的名称(
console1
console2
等)…

我确实在网上看到了一个使用AppDomain的示例,但我不太明白如何使用。如何使我的程序集在某个AppDomain中被引用?没关系。我在这里找到了答案:还有别的办法吗?我一直在玩AppDomain给我带来了很多麻烦。我需要能够向脚本发送对象引用,但它会抛出一个奇怪的“object not serializable”异常。@Darwin,对不起,我自己对AppDomains了解不够。不过,您的对象需要从一个特殊的基类派生。是不是
MarshalByRef
?这就是我为什么要寻找其他选项的原因,因为我现在的处境是,我无法让所有东西都从MarshalByRef派生。