Como fazer com que o IIS7 libere um arquivo bloqueado?

25

Durante nossas compilações de produção, um arquivo estático muito grande (10 megabytes) no diretório raiz às vezes é bloqueado pelo IIS e não pode ser excluído pela tarefa limpa. Provavelmente, isso está sendo atendido ativamente a um ou mais clientes no momento.

O processo de compilação interrompe o site antes de limpar via

c:\Windows\System32\inetsrv\appcmd.exe stop site http://oursite.com

No entanto, isso não libera o arquivo - precisamos reiniciar o IIS para que o processo abandone seu bloqueio.

appcmd.exepermite derrubar o IIS completamente; nós não queremos fazer isso!

Existem outras maneiras de obter o IIS para liberar um arquivo bloqueado, sem reiniciar o IIS? Simplesmente parar e iniciar o site individual definitivamente não está funcionando para liberar o bloqueio do arquivo.

Jarrod Dixon
fonte
11
Pergunta séria agora: esse arquivo estático muda de compilação para compilação ou é apenas um arquivo que nunca será alterado?
Splattne 10/05/09
Apenas um pensamento louco, mas eu me pergunto o que aconteceria se você ativasse as Cópias de Sombra nesta pasta?
1013 Richard West
Este é o seu sitemap.xml, certo?
Dave Cheney
Sim, era o nosso sitemap.xml, mas agora temos apenas uma rota MVC e armazenamos em cache o otário na memória. Não há mais bloqueio!
Jarrod Dixon

Respostas:

12

Existem ferramentas, como o Process Explorer da Sysinternal, que podem encontrar e fechar forçosamente os identificadores de arquivo, no entanto, o estado e o comportamento do aplicativo (tanto o seu quanto, neste caso, o IIS) depois de fazer isso são indefinidos. Alguns não se importam, alguns cometem erros e outros caem com força.

A solução correta é interromper a interrupção e permitir que o IIS libere bloqueios de forma limpa e faça a limpeza após si próprio para preservar a estabilidade do servidor. Se isso não for possível, você pode criar outro site na mesma caixa ou configurar uma nova caixa com o novo conteúdo e mover o nome do domínio / IP para "promover" o novo conteúdo para produção.

Greg Work
fonte
2
+1 para o Process Explorer, ele pode lhe dar algumas dicas para ser capaz de resolver o problema se você pode ver o que segmento está segurando a alça de arquivo aberto
Nick Kavadias
Talvez muito útil liberado arquivo bloqueado por meio de programação usando ferramentas Sysinternals com Powershell , C # ou scripts de bat-cmd
Kiquenet
Eu tenho o IIS para desbloquear o arquivo ou diretório simplesmente tentando copiar arquivos para essa pasta controlada pelo IIS e exibindo o aplicativo Web em um navegador. Às vezes, esse processo desbloqueia essas alças.
Marc Maron
13

Eu uso uma pequena ferramenta chamada "Handle" para fazer isso.

Você basicamente passa o nome do arquivo bloqueado e informa quais processos estão sendo usados:

handle c:\weird.file
Something.exe pid: 1000 100: C:\weird.file
Something.exe pid: 1000 101: C:\weird.file

Em seguida, você passa a opção -c para fechar o identificador:

handle.exe -c 101 -p 1000 -y
handle.exe -c 100 -p 1000 -y

Você pode se esforçar para trabalhar isso em um script de construção sem um programa de wrapper para analisar a saída, mas espero que isso ajude.

Simon Johnson
fonte
O poderoso Mark Russinovich para o resgate - vou verificar isso, mas o aviso terrível de Handle sobre a instabilidade do programa ao fechar um identificador à força me deixa nervoso.
Jarrod Dixon
Esperamos que qualquer instabilidade seja limitada ao AppPool em questão. Se for esse o caso, basta reiniciar o AppPool depois de liberar o bloqueio.
Simon Johnson
@ Jarrod: alguma sorte? Você poderia postar algum resultado, em seu post original, por favor? Eu adoraria ver o que está acontecendo aqui, nos bastidores.
Pure.Krome
Talvez muito útil liberado arquivo bloqueado programaticamente usando Handle com Powershell , C # ou scripts de bat-cmd e obter processos que travam uma pasta
Kiquenet
5

Não tenho certeza se você quer dizer a compilação de arquivos aspx em assemblies temporários. Estamos usando projetos de implantação do ASP.NET , que pré-compilam todos os arquivos aspx / ascx antecipadamente.

Ao copiar os arquivos binários da pasta "publicar" para a pasta "bin", ativamos temporariamente um arquivo app_offline.htm que é removido após a cópia de todos os assemblies (apenas alguns segundos). Dessa forma, nunca experimentei bloqueios de arquivos.

EDITAR:

Você pode tentar reciclar o pool de aplicativos usando appcmd.exe, em vez de parar o site:

C:\Windows\System32\inetsrv\appcmd.exe recycle apppool "My App Pool Name"
splattne
fonte
11
Não, é apenas um arquivo de conteúdo estático no diretório raiz - atualizando a pergunta com essas informações!
Jarrod Dixon
11
Eu acho que você está usando o app_offline.htm durante a execução do seu trabalho de criação?
Splattne
Acho que tentamos reciclar manualmente sem sucesso, mas tentaremos novamente na próxima vez que houver um bloqueio (os pools de aplicativos são para .NET, certo? Provavelmente não ajudará aqui). Costumávamos criar o arquivo app_offline.htm, mas não ajudava no bloqueio - e foi por isso que decidimos remover o site individualmente.
Jarrod Dixon
Receio que você esteja certo. Vou testar isso em um de nossos servidores e retornar para você.
Splattne 10/05/09
11
@ splattne: A reciclagem do pool de aplicativos deveria ter removido a alça, desde que o arquivo tenha sido aberto pelo site. Se a reciclagem do pool não ajudar, meu palpite é que outra coisa bloqueia o arquivo.
Pbz 11/05/09
1

O Process Monitor deve ajudá-lo com sua investigação. Aqui está um exemplo do blog de Mark ( o cara que escreveu a ferramenta) sobre como encontrar o identificador de arquivo.

Você pode tentar esta ferramenta Unlocker para automatizar seu desbloqueio no nível do identificador de arquivo.

Nick Kavadias
fonte
Legal, nunca usei o Process Monitor; mas todas as estações de trabalho que eu uso imediatamente recebem o Process Explorer! technet.microsoft.com/en-us/sysinternals/bb896653.aspx
Jarrod Dixon
1

Não é a resposta, mas uma idéia alternativa, caso não haja como "desbloquear" esse arquivo sem reiniciar o servidor IIS:

E se você criar / implantar em uma nova pasta vazia e alterar o diretório inicial do site para essa pasta? Você precisa criar um novo nome de pasta ou alternar entre dois nomes.

Não sei em qual pasta esse arquivo pertence. Se não precisar estar na pasta raiz, você poderá colocá-lo em uma pasta recém-criada e criar um diretório virtual apontando para essa pasta. Assim, você pode manter seu diretório inicial padrão para o aplicativo.

splattne
fonte
1

Eu tive o mesmo problema. Agora mudei para o MSDeploy (Web Deploy) e agora posso atualizar o site de maneira confiável sem parar nada. De fato, esta etapa está em script em nossa ferramenta de criação automatizada e acontece o tempo todo sem problemas. E é rápido também.

realMarkusSchmidt
fonte
0

Claro, pare o serviço IIS. Talvez eu não esteja entendendo alguma coisa, desculpe.

Mark Allen
fonte
2
Se você está parando o serviço IIS, você vai derrubar todos os sites ...
splattne
Essa é a única coisa que realmente queremos evitar, pois não queremos que o site CruiseControl.NET seja lançado - clicamos no botão "Atualizar status" como loucos durante uma compilação para verificar se há sucesso!
Jarrod Dixon
Ok, que tal construir em outro lugar primeiro e depois implantar sobre o arquivo estático em vez de fazer tudo naquele servidor?
Mark Allen
não é esse o problema aqui? Ninguém disse que o arquivo estava sendo modificado pelo software no próprio servidor.
FlavorScape 9/08/12
0

Nota: não é especialista em semântica de bloqueio de arquivos do Windows

Jarrod, você é capaz de renomear o arquivo fora do caminho. Você também pode criar seu novo arquivo com uma extensão temporária e renomeá-lo sobre o arquivo atual.

Se a semântica de bloqueio de arquivos do Windows funcionar de maneira semelhante à do POSIX, os leitores que mantêm um bloqueio de leitura atual no arquivo ainda devem continuar servindo o arquivo antigo até fechar seus fluxos de leitura, enquanto novos leitores abrirão o novo arquivo.

Dave Cheney
fonte
Não, não podemos fazer nada com o arquivo até que o IIS seja reiniciado.
Jarrod Dixon