Substituindo arquivos .dll enquanto o aplicativo está sendo executado?

18

Eu tenho vários servidores de jogos que usam um determinado arquivo .dll para executar. Às vezes, preciso atualizar os servidores de jogos, mas não quero interromper os jogos que já estão em execução.

Existe uma maneira de substituir o arquivo .dll (está bloqueado pelo Windows) para que as próximas instâncias dos servidores de jogos que usam esse arquivo abram a nova versão, e as antigas continuem usando a versão antiga desse arquivo .dll até que sejam reiniciadas ?

É seguro desbloquear o arquivo usando uma dessas ferramentas que o fazem e substituí-lo?


fonte
Talvez não seja o seu jogo. No entanto, o Chrome é atualizado sem interromper seu processo. Infelizmente, isso é específico do aplicativo. (Vá para %LocalAppData%\Google\Chrome\Applicatione você deve ver pastas como 26.0.1410.64que armazena DLLs de versões diferentes)
Alvin Wong
Dependendo do software em questão, pode ser possível instalar e executar duas ou mais instâncias distintas (em locais diferentes). Ineficiente, mas talvez viável.
Harry Johnston

Respostas:

23

Na verdade, você pode e geralmente funciona sem nenhum problema (embora nem sempre)

O que você faz é renomear o arquivo sem movê-lo e mover o novo arquivo sobre ele. Isso manterá os identificadores do arquivo válidos e funcionando, para que instâncias preexistentes ainda possam acessar o arquivo corretamente e novas instâncias (ou novos identificadores) irão para o novo arquivo.

Obviamente, se um programa reabrir o mesmo arquivo dll e esperar que ele permaneça exatamente o mesmo (por exemplo, se houver recursos a serem carregados a partir da dll e que as referências a esses recursos sejam extraídas do código em execução quando a dll for carregada) ), isso causará problemas, mas essa definitivamente não é a norma.

Stephane
fonte
11

Não. Embora uma DLL possa ser totalmente mapeada na memória física enquanto o aplicativo é executado, definitivamente não há garantia disso. Partes de DLLs (e até executáveis) podem ser mapeadas para a RAM enquanto outros bits permanecem no disco e podem ser lidas posteriormente.

Alterar o arquivo no disco enquanto o Windows possui alguns bits mapeados na RAM não terminaria bem. O Windows bloqueia por um bom motivo.

Editar: preciso esclarecer algo, pois algumas pessoas parecem ter a intenção de culpar o Windows pelo que é realmente um problema de design de aplicativo , não um problema de design do sistema operacional.

Você pode atualizar as DLLs que os aplicativos usam no Windows sem encerrar o processo, mas o aplicativo deve ter sido gravado de forma que possa ser sinalizado para descarregar o assembly, aguardar o término da atualização e recarregar a DLL. Isso não tem nada a ver com o sistema operacional em execução. É um problema de design de aplicativo.

Editar: consulte também a resposta de Stephane para uma possível solução que possa funcionar, dependendo de como o aplicativo específico responde à alteração da DLL. Eu acho que ele merece um voto positivo.

Ryan Ries
fonte
Existe alguma maneira de mover esse arquivo para um local temporário para que possa ser excluído mais tarde, enquanto coloca um novo em seu local antigo (para que os servidores que iniciam depois disso usem a nova dll)? Ou o identificador do arquivo está vinculado ao local do arquivo?
Isso depende inteiramente de como o aplicativo é gravado / como ele usa DLLs. Dê uma olhada na resposta de Greg Askew. Se o identificador de arquivo estiver aberto, não há muito o que fazer. Você pode fechar à força o identificador do arquivo, mas quase certamente travará pelo menos o seu aplicativo, se não todo o sistema operacional.
Ryan Ries
Então, qual é esse "bom motivo"? Até agora, sua resposta não contém uma razão convincente para a Microsoft não oferecer a capacidade de troca a quente.
Konrad Rudolph
2

Não, você não deve mexer com as alças de arquivo existentes.

Se você pode assumir o controle do carregamento da montagem e especificar que ele seja aberto com FileShare.Delete, será possível renomeá-lo. Os processos existentes continuarão a fazer referência à montagem renomeada.

/programming/7147577/programmatically-rename-open-file-on-windows .

Greg Askew
fonte
2
Na minha experiência, na maioria dos casos (bem, mais da metade do tempo, de qualquer forma), você pode renomear (mas não excluir) uma DLL sem mexer no aplicativo.
Harry Johnston
@HarryJohnston: Sim, parece que posso renomear o arquivo .dll, mesmo que esteja em uso. Acho que vou fazer isso a partir de agora.
1

Não, infelizmente não é possível.

Desculpe, para ser exato, a menos que haja ligação tardia, o que significa que o aplicativo usa essa dll quando executa alguma parte do código nessa dll, mas ainda não é confiável.

Danila Ladner
fonte
1

Você pode ver como o processo hospedado asp.net funciona e desenvolver algo semelhante.

Ele pega o aplicativo da Web inteiro e o move para um local temporário a partir do qual o aplicativo é realmente carregado. Em seguida, deixa um processo para monitorar as alterações na pasta original, quando detectada, gera uma nova instância do aplicativo em um novo local temporário e começa a redirecionar novas solicitações para esse aplicativo. O aplicativo antigo é desativado assim que as solicitações pendentes são concluídas.

(Nitpicking, sim, é uma visão simplificada das coisas, na maioria dos casos o IIS enfileira as solicitações até que o novo aplicativo possa assumir o controle)

Thomas James
fonte
0

Cerca de uma década atrás, eu era um usuário feliz de http://www.eggcentric.com/ISAPILoader.htm que viveu a troca de dll ISAPI do IIS. Egg ainda está apoiando sua solução FOSS.

jkellydresser
fonte
0

O NSIS Installer tem uma opção como Mover para Temp na reinicialização da máquina, o SO sinaliza alguns arquivos para serem movidos para um local diferente na próxima inicialização, na próxima inicialização da máquina esses arquivos sinalizados passam automaticamente para o novo local selecionado anteriormente. Uma pequena pesquisa sobre isso fará você feliz nesse aspecto.

Shashank Kandhawe
fonte
Você poderia fornecer uma resposta completa em sua resposta, em vez de dizer ao OP para procurar uma solução. Ele não estaria aqui perguntando se ele já havia encontrado uma solução. Obrigado.
John aka hot2use