Pergunta

Se você usar o CodeDomProvider classe .NET depois que a compilação estiver concluída, você não pode excluir o conjunto de saída.Eu quero ser capaz de excluir o conjunto de saída.Arquivo.Excluir retorna um acesso negado a exceção.

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
}

Editar Como contornar eu estou usando um construtor estático na classe que procura a pasta temp e elimina criado anteriormente assembléias.

Foi útil?

Solução

Eu suspeito que o problema é que a assemblagem é carregada (em memória), e tem o arquivo de saída em aberto, assim como qualquer outra montagem que está atualmente carregado terá um identificador para o seu arquivo executável.

É também possível (apesar de eu considerar que é improvável) que a instância de dom ou a CompilerResults instância tem uma referência para o arquivo aberto.Nem é IDisposable, então eu suspeito que eles não estão mantendo o arquivo aberto.

Possíveis soluções:

Você pode compilar o assembly para a memória.Isto é, não um arquivo de saída.O que resolve o problema imediato.No entanto, você ainda tem o problema de que o assembly compilado permanece na memória.Não há nenhuma maneira de descarregar uma assembléia, sem derrubar o domínio de aplicação.

Você pode criar um aplicativo separado de domínio para fazer a compilação e, em seguida, comunicar os resultados de volta para o seu principal domínio de aplicação.Em seguida, você pode desligar o compilador domínio de aplicação, que irá remover o assembly compilado a partir da memória e também divulgar quaisquer identificadores de ficheiro que está a referenciar o arquivo que você acabou de criar.O programa principal pode, em seguida, exclua o arquivo em questão.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top