【发布时间】:2020-02-20 19:49:39
【问题描述】:
我必须在运行时更改 .dll 文件的内容,但不能这样做,因为它正在使用中并得到一个
无效操作异常
改为。
我目前正在研究一种在运行时为 Unity 制作的游戏编译 C# 代码的方法。使用Microsoft.CSharp.CSharpCodeProvider 和System.CodeDom.Compiler.CompilerParamters 类,我有一个系统工作,允许我编译代码并将其输出为.dll 文件,因此我可以将它与其他类一起使用。如果您需要了解更多关于我这样做的方式,请查看我使用的the tutorial(以及下面提到的更改)。
但是,编译只工作一次,因为下次运行编译器时,.dll 文件已经存在,我收到以下错误消息:
无法写入文件“fileName”。 Win32 IO 返回 1224。路径:path/fileName.dll
这些是我的代码中最重要的部分:
public void Compile() {
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
//...
parameters.GenerateInMemory = false; //generates actual file
parameters.GenerateExecutable = false; //generated .dll instead of .exe
//...
parameters.OutputAssembly = Application.dataPath + className + ".dll";
CompilerResults results = provider.CompileAssemblyFromSource(parameters, code);
//...
Assembly assembly = results.CompiledAssembly;
Type program = assembly.GetType("GameLevel." + className);
MethodInfo excecuteMethod = program.GetMethod("Excecute");
excecuteMethod.Invoke(null, null);
}
我真的不想每次都给文件一个不同的名字,因为那样会让在其他类中使用它很痛苦。我假设这可以通过以某种方式告诉游戏不再使用旧的 .dll 文件来解决,因为在方法执行后甚至不应该是这种情况,对吧?
感谢您的回答!
【问题讨论】:
-
File.Delete(Application.dataPath + className + ".dll");跑之前?
-
"因为在方法被执行之后甚至不应该是这种情况,对吧?" - 方法在类型中(
DynamicMethod除外);类型在程序集中;程序集位于应用程序域中,无法卸载;释放 dll 的唯一方法是杀死应用程序域或进程,在 .NET Core 中:应用程序域 不存在 (所以:你必须杀死进程)。根据您的复杂程度,我想知道您是否可以使用可收集的DynamicMethod/Expression等待 -
只需给新的 dll 起一个不同的名称。并确保当你实例化类时,它来自新的 dll
-
顺便说一句,我实际上这样做并且工作正常。我的 dll 名称和类名也是动态的。
-
@bizzehdee 给我错误:System.UnauthorizedAccessException:对路径“path/fileName.dll”的访问被拒绝。
标签: c# code-generation