Eu acredito que um arquivo de bloqueio é a solução confiável mais simples. O truque é garantir que o processo em lote em execução mantenha um bloqueio de gravação exclusivo no arquivo até que seja finalizado. A beleza deste sistema é que o Windows irá liberar o bloqueio, não importando o motivo pelo qual o lote termine.
Depois de ter um arquivo de bloqueio, você precisa de uma maneira de detectar se o arquivo está bloqueado no momento. Eu descrevo como fazer isso em Como verificar na linha de comando se um determinado arquivo ou diretório está bloqueado (usado por qualquer processo)?
Eu usei essa técnica primitiva, mas eficaz, para realizar algumas tarefas bastante sofisticadas com o lote do Windows:
- Execução paralela de uma lista de tarefas, limitando o número total de processos simultâneos
- Como você compartilhou arquivos de log no Windows?
- Serialize a execução do symstore via Powershell ou BATCH
Você não sabe onde o arquivo de lote reside - na máquina remota ou na máquina local, ou se você pode estar executando o script em várias máquinas simultaneamente, mas apenas um processo ativo por máquina.
Se o script em lote estiver na máquina remota e seu processo tiver acesso de gravação ao script, você poderá usar o próprio arquivo em lote como o arquivo de bloqueio! Você só precisa chamar uma sub-rotina ao redirecionar um identificador de arquivo não usado para o script em lote usando o modo de anexação. A CHAMADA falhará se outro processo já tiver um bloqueio. O bloqueio será liberado automaticamente quando o script terminar (independentemente de como ele termina).
myscript.bat
@echo off
:: Note - this extra call is to avoid a bug with %~f0 when the script
:: is executed with quotes around the script name.
call :getLock
exit /b
:getLock
:: The CALL will fail if another process already has a write lock on the script
call :main 9>>"%~f0"
exit /b
:main
:: Body of your script goes here. Only one process can ever get here
:: at a time. The lock will be released upon return from this routine,
:: or when the script terminates for any reason
exit /b
Se o seu script estiver em uma máquina diferente do processo, mas você só tiver o processo em execução em uma máquina por vez, acho que o processo acima ainda funcionará.
Talvez uma alternativa melhor seja estabelecer um arquivo de bloqueio dedicado em cada máquina remota, separado do script em lote. Então você pode executar o processo em quantas máquinas remotas quiser.