CodeDomProvider 컴파일에 의해 생성 된 어셈블리를 삭제하는 동안 액세스가 거부 되었습니까?

StackOverflow https://stackoverflow.com/questions/6035846

문제

컴파일이 완료된 후 .NET에서 CodedomProvider 클래스를 사용하는 경우 출력 조립품을 삭제할 수 없습니다.출력 조립품을 삭제할 수 있기를 원합니다.file.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
}
.

편집 임시 폴더를 검색하고 이전에 생성 된 어셈블리를 삭제하는 클래스의 정적 생성자를 사용하고 있습니다.

도움이 되었습니까?

해결책

I suspect the problem is that the assembly is loaded (in memory), and has the output file open, just as any other assembly that is currently loaded will have a handle to its executable file.

It's also possible (although I consider it unlikely) that the dom instance or the CompilerResults instance has a reference to the opened file. Neither is IDisposable, so I suspect they're not holding the file open.

Possible solutions:

You can compile the assembly to memory. That is, don't output a file. That solves the immediate problem. However, you still have the problem that the compiled assembly remains in memory. There's no way to unload an assembly without tearing down the app domain.

You can create a separate app domain to do the compile, and then communicate the results back to your main app domain. You can then shut down the compiler app domain, which will remove the compiled assembly from memory and also release any file handles that are referencing the file you just created. Your main program can then delete the file in question.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top