0

I've got a batch script start.bat that creates a locked .lock file (basically, to verify if the script is running, by attempting to delete it) and starts a bunch of secondary looping batch scripts (they keep on running after start.bat is closed). The problem is when start.bat is closed the locked file remains locked, until ALL of the secondary scripts are closed.

Question: Are there any alternative methods to run secondary batch scripts without locking up the primary script until secondary ones are finished?

I feel like most of this code is irrelevant, but included it in case somebody wants to test it.

@echo off
set "started="
<nul >"%~nx0.lock" set /p ".=." ::Rewrite lock file with a single dot
2>nul (
  9>>"%~f0.lock" (
  set "started=1"
  call :start
 )
)
@if defined started (
    del "%~f0.lock">nul 2>nul
) else (
    exit //script closes
)
exit /b

:start
//irrelevant loop logic
Start pause.bat //Pause command to keep pause.bat open
//starts other batch files too
Zero
  • 1,562
  • 1
  • 13
  • 29

2 Answers2

0

Seems like the file may still be in use?

Try:

del /F "%~f0.lock">nul 2>nul
0

Your problem are inherited handles. When you start a process with a redirection active, the process inherits the redirection. So, you need to keep the lock but start the processes while not keeping it.

You can try some variation of this

@echo off
    setlocal enableextensions disabledelayedexpansion

    rem Check if this is a lock instance
    if "%~1"==".LOCK." goto :eof

    rem Retrieve all the needed data to handle locking
    call :getCurrentFile f0
    for %%a in ("%f0%") do set "lockFile=%%~nxa.lock"
    set "lockID=%random%%random%%random%%random%%random%%random%%random%"

    rem Try to adquire lock
    set "started="
    2>nul (
        >"%lockFile%" (
            rem We get the lock - start a hidden instance to maintain the lock
            set "started=1"
            start "" /b cmd /k""%f0%" .LOCK. %lockID%"
        )
    )

    rem Check if the lock was sucessful
    if not defined started (
        echo lock failed
        pause
        goto :eof
    )

    rem Launch the child processes, now detached from lock, as this cmd instance
    rem is not holding it. The hidden cmd /k instance holds the lock
    start "" write.exe
    start "" notepad.exe
    start "" /wait winver.exe

    rem Once done, release the locked instance
    >nul 2>nul (
        wmic process where "name='cmd.exe' and commandline like '%%.LOCK. %lockid%%%'" call terminate
    )

    rem And remove the lock file
    del "%lockFile%"

    rem Done
    goto :eof

rem To prevent problems: http://stackoverflow.com/q/12141482/2861476        
:getCurrentFile returnVar
    set "%~1=%~f0"
    goto :eof

As the hidden cmd instance is hosted inside the same console than the current batch file, if you close the console, the lock is released (but the lock file is not deleted)

MC ND
  • 69,615
  • 8
  • 84
  • 126