C# - Access Denied Deleting a File - Procmon

Você escreveu seu código e na hora de testar você move, lê informações que fazem parte do arquivo ou cria um arquivo e depois que o processamento terminou você quer apagar o arquivo e se depara com o erro a seguir.

Access to the path 'C:\Program Files\ReportingServices.Extension.dll' is denied.

Então a primeira coisa que pensamos é: faltou usar using em algum lugar para que o Dispose pattern faça o seu trabalho. E aí você percebe que não é isso e abre-se um buraco no chão bem na sua frente. E agora qual é o processo que está rodando e usando o arquivo além do seu próprio software?

Debug novamente, break point antes da remoção do arquivo, aí manualmente você entra na pasta, e del no arquivo e o arquivo se foi pra lixeira... e um novo buraco abre-se no chão, porque suas alternativas de tentar solucionar o problema estão se esgotando. Esta opção de excluir o arquivo manualmente poderia te mostrar que o arquivo não poderia ser excluído por estar sendo usado por outra aplicação exibindo qual aplicação está usando o arquivo, mas não foi o caso.

Procmon - Process Monitor - Sysinternals

O ano de 2020 eu ouvi muito sobre como usar ferramentas que apoiam na solução de problemas e de fato há várias que ajudam muito no dia a dia e a ferramenta Procmon é uma delas, você pode encontrar outras no site da Microsoft Sysinternals.

Esta ferramenta monitora o que está acontecendo com os processos que estão rodando, o que e onde estão manipulando informações, inclusive o que acontece com arquivos, que é o meu caso aqui.

Como eu sabia qual arquivo e onde ele estava, eu coloquei um filtro pela pasta conforme configurado na imagem a seguir.

Procmon Filter Add Path

Depois disso eu executei meu software que estava apresentando o erro de exclusão do arquivo e uma série de instruções foram apresentadas até onde o erro ocorreu como mostrado e destacado em vermelho na imagem a seguir.

Process Monitor Procmon Access Denied

Vamos a alguns detalhes:

FILE LOCKED

Na primeira linha é exibido uma instrução ocorrida com o arquivo que eu queria excluir, chamada FILE LOCKED, eu não sabia o que significava, mas lembrei de algumas mensões do meu tech leader sobre lock de arquivos e fiz uma simples pesquisa para auxiliar no entendimento.

Então, esta linha mostra que o Visual Studio (devenv.exe) realizou uma ação com o arquivo que causou o lock e que este lock não foi liberado, o seja se eu tentasse excluir o arquivo neste momento apareceria aquela famosa mensagem de que o arquivo não pode ser excluído/alterado pois está sendo usado.

CANNOT DELETE

Esta última instrução é do meu software, que tentou excluir o arquivo e não conseguiu, pois o arquivo está em lock pelo Visual Studio.

Causas

Pesquisando um pouco mais, descobri que em um trecho do meu código eu lia o arquivo para pegar o número da versão para poder usar esta informação mais adiante e a forma com que eu estava enviando esta instrução fazia com que o arquivo ficasse em lock

Assembly assembly = Assembly.LoadFrom(@"C:\Program Files\ReportingServices.Extension.dll");  

A solução foi mudar a forma de pegar a informação para que o arquivo não ficasse mais em lock e pudesse ser excluído, então eu alterei para o código a seguir

byte[] assemblyBytes = File.ReadAllBytes(@"C:\Program Files\ReportingServices.Extension.dll");  
var assembly = Assembly.Load(assemblyBytes);  

E pronto! problema resolvido