C# 删除由CodeDomProvider创建的程序集时拒绝访问?

C# 删除由CodeDomProvider创建的程序集时拒绝访问?,c#,file-io,access-denied,delete-file,dynamic-compilation,C#,File Io,Access Denied,Delete File,Dynamic Compilation,如果编译完成后在.NET中使用CodeDomProvider类,则无法删除输出程序集。我希望能够删除输出程序集。Delete返回一个拒绝访问的异常 string asmPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N") + ".exe"); string keyPath = "some path to a *.snk file that works"; // build compiler CodeDomProv

如果编译完成后在.NET中使用CodeDomProvider类,则无法删除输出程序集。我希望能够删除输出程序集。Delete返回一个拒绝访问的异常

string asmPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N") + ".exe");
string keyPath = "some path to a *.snk file that works";
// build compiler
CodeDomProvider dom = CodeDomProvider.CreateProvider("VisualBasic");
CompilerParameters cp = new CompilerParameters();
cp.TreatWarningsAsErrors = false;
cp.GenerateInMemory = false;
cp.GenerateExecutable = true;
cp.CompilerOptions = "/target:winexe /keyfile:\"" + keyPath + "\"";
cp.OutputAssembly = asmPath;
// add all the other assembly references
string netPath = @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\";
cp.ReferencedAssemblies.Add(netPath + @"System.dll");
cp.ReferencedAssemblies.Add(netPath + @"System.Core.dll");
cp.ReferencedAssemblies.Add(netPath + @"System.Data.dll");
cp.ReferencedAssemblies.Add(netPath + @"System.Xml.dll");
CompilerResults cr = dom.CompileAssemblyFromSource(cp, new string[] { code });
if (cr.Errors.Count == 0)
{
    cr.TempFiles.Delete();
    dom.Dispose();
// do stuff
...
//
    File.Delete(asmPath); // fails here Access Denied
}

作为变通方法进行编辑我在类上使用静态构造函数搜索临时文件夹并删除以前创建的程序集。

我怀疑问题在于程序集已加载(在内存中),并打开了输出文件,就像当前加载的任何其他程序集都有其可执行文件的句柄一样

也有可能(虽然我认为不太可能)DOM实例或 CuffeleRebug < /Calp>实例对打开的文件有引用。两者都不是可识别的,所以我怀疑他们没有打开文件

可能的解决办法:

您可以将程序集编译到内存中。也就是说,不要输出文件。这就解决了眼前的问题。但是,仍然存在编译后的程序集仍保留在内存中的问题。如果不拆下应用程序域,就无法卸载程序集


您可以创建一个单独的应用程序域来进行编译,然后将结果传回主应用程序域。然后可以关闭编译器应用程序域,这将从内存中删除编译后的程序集,并释放引用刚刚创建的文件的任何文件句柄。然后,您的主程序可以删除有问题的文件。

我没有任何问题。请禁用病毒扫描程序。他们对一个不知从哪里冒出来的DLL太兴奋了。在循环中任意休眠一段时间是不完美的解决方法。使用应用程序域作为编译代理似乎是唯一的解决方案。正在编译的代码是一个客户端生成的脚本,因此,我已经有一个单独的应用程序域(权限较低)来运行它。我想避免另一个应用程序域(具有编译权限)来生成程序集。