如何卸载 CSharpCodeProvider 创建的程序集?
How to unload assembly created by CSharpCodeProvider?
问题
CSharpCodeProvider 可用于将源 .cs 文件编译成程序集。
但是,默认情况下程序集会自动加载到 AppDomain.CurrentDomain 中。在我的例子中,这是一个问题,因为我需要能够在运行时再次重新编译程序集,并且由于它已经加载到 CurrentDomain 中,我无法卸载它,所以我被卡住了。
我查看了文档,似乎无法设置目标应用域。我也尝试在 Google 上搜索它,但只在使用 Assembly.Load 的地方找到答案,我认为我不能使用它,因为我需要从原始源代码编译,而不是 .dll
人们会怎么做呢?有任何替代方案或解决方法吗?
主程序
using (var provider = new CSharpCodeProvider())
{
param.OutputAssembly = "myCompiledMod"
var classFileNames = new DirectoryInfo("C:/sourceCode").GetFiles("*.cs", SearchOption.AllDirectories).Select(fi => fi.FullName).ToArray();
CompilerResults result = provider.CompileAssemblyFromFile(param, classFileNames);
Assembly newAssembly = result.CompiledAssembly // The assembly is already in AppDomain.CurrentDomain!
// If you try compile again, you'll get an error; that class Test already exists
}
C:/sourceCode/test.cs
public class Test {}
我已经试过了
我已经尝试创建一个新的 AppDomain 并将其加载到其中。发生的事情是程序集最终被加载到两个域中。
// <snip>compile code</snip>
Evidence ev = AppDomain.CurrentDomain.Evidence;
AppDomain domain = AppDomain.CreateDomain("NewDomain", ev);
domain.Load(newAssembly);
答案是使用 CSharpCodeProvider().CreateCompiler() 而不仅仅是 CSharpCodeProvider,并将 param.GenerateInMemory 设置为 false。现在我可以看到行号并且没有创建可见的程序集 .dll 文件,尤其是没有被锁定。这允许将程序集保留在内存中并在需要时重新加载它。
问题
CSharpCodeProvider 可用于将源 .cs 文件编译成程序集。 但是,默认情况下程序集会自动加载到 AppDomain.CurrentDomain 中。在我的例子中,这是一个问题,因为我需要能够在运行时再次重新编译程序集,并且由于它已经加载到 CurrentDomain 中,我无法卸载它,所以我被卡住了。
我查看了文档,似乎无法设置目标应用域。我也尝试在 Google 上搜索它,但只在使用 Assembly.Load 的地方找到答案,我认为我不能使用它,因为我需要从原始源代码编译,而不是 .dll
人们会怎么做呢?有任何替代方案或解决方法吗?
主程序
using (var provider = new CSharpCodeProvider())
{
param.OutputAssembly = "myCompiledMod"
var classFileNames = new DirectoryInfo("C:/sourceCode").GetFiles("*.cs", SearchOption.AllDirectories).Select(fi => fi.FullName).ToArray();
CompilerResults result = provider.CompileAssemblyFromFile(param, classFileNames);
Assembly newAssembly = result.CompiledAssembly // The assembly is already in AppDomain.CurrentDomain!
// If you try compile again, you'll get an error; that class Test already exists
}
C:/sourceCode/test.cs
public class Test {}
我已经试过了
我已经尝试创建一个新的 AppDomain 并将其加载到其中。发生的事情是程序集最终被加载到两个域中。
// <snip>compile code</snip>
Evidence ev = AppDomain.CurrentDomain.Evidence;
AppDomain domain = AppDomain.CreateDomain("NewDomain", ev);
domain.Load(newAssembly);
答案是使用 CSharpCodeProvider().CreateCompiler() 而不仅仅是 CSharpCodeProvider,并将 param.GenerateInMemory 设置为 false。现在我可以看到行号并且没有创建可见的程序集 .dll 文件,尤其是没有被锁定。这允许将程序集保留在内存中并在需要时重新加载它。