如何在运行时在C#中写入生成的.dll文件?

问题描述 投票:1回答:1

我必须在运行时更改.dll文件的内容,但不能这样做,因为它正在使用中并得到一个]

InvalidOperationException

代替。

我目前正在研究一种在Unity上运行的游戏在运行时编译C#代码的方法。使用Microsoft.CSharp.CSharpCodeProviderSystem.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文件来解决此问题,因为执行该方法后甚至不应该这样,对吧?

感谢您的回答!

c# code-generation
1个回答
0
投票

正如我在评论中说的,我经常会曲解。我有一个编译公式的演算引擎。每当公式更改时,都会对其进行重新编译。每当我需要运行公式时,我都会实例化其类。但....每次重新编译时,我都会使用不同的名称创建一个新的dll。因此,我将时间戳用作名称,将时间戳用作类名称。每次实例化时,我都会寻找最新的dll

所以我在DLL中的类看起来像:

public class MyGeneratedClass_20191024103000 {
// do stuff
}

程序集创建(伪代码):

aseemblyManager.CreateLibrary(OUTPUT_DLLS_PATH + "\\Calculus_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".dll", refs, sourcecode) ... etc

组装负载:

string pathNewest = ListFolderSortByDate(); //you should also get the timestamp
assembly = Assembly.LoadFrom(pathNewest ); //register dll
mytype =  assembly.GetType("mycalculus"); 

最后,实例化:

 myobject= Activator.CreateInstance(mytype , new object[] { some parameters });
mytype .GetMethod("Calculate" + timestamp).Invoke(myobject, arrParam);
© www.soinside.com 2019 - 2024. All rights reserved.