在辅助脚本关闭之前,启动命令不允许脚本完全关闭

时间:2017-02-27 10:46:34

标签: batch-file locking

我有一个批处理脚本start.bat,它创建一个锁定的.lock文件(基本上,通过尝试删除它来验证脚本是否正在运行)并启动一堆二级循环批处理脚本(它们在start.bat关闭后继续运行)。问题是当start.bat关闭时,锁定的文件保持锁定状态,直到所有辅助脚本都关闭。

问题:是否有其他方法可以运行辅助批处理脚本而不会锁定主脚本,直到辅助脚本完成为止?

我觉得这些代码大部分都是无关紧要的,但是如果有人想测试的话,请将其包含在内。

@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

2 个答案:

答案 0 :(得分:0)

好像文件可能仍在使用中?

尝试:

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

答案 1 :(得分:0)

您的问题是继承句柄。当您启动重定向活动的进程时,该进程将继承重定向。因此,您需要保持锁定,但在不保留锁定的情况下启动进程。

你可以试试这个

的一些变化
@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

由于隐藏的cmd实例托管在与当前批处理文件相同的控制台内,因此如果关闭控制台,则会释放锁定(但锁定文件不会被删除)