bat避免重复运行

方法一:

@echo off 2>nul 3>>"%~f0"
type "%~f0"

rem 脚本内容...

方法二:

@echo off

set SCRIPT_NAME=%~nx0
set COUNT=
for /F "delims=" %%i in ('wmic process get Caption^,CommandLine ^| find /i "%SCRIPT_NAME%" ^| find /v /c "find.exe"') do (
    set COUNT=%%i
)
if %COUNT% GTR 1 (
    echo 监控进程已存在
    exit /B 1
)

rem 脚本主体内容...

方法三:

@echo off
set SCRIPT_NAME=%~nx0
set MARK_FILE="%TEMP%\%SCRIPT_NAME%.lock"

:: 创建守护进程
start "" cmd /c "%~dp0cleanup.bat" "%MARK_FILE%"
:: 检查 lock 文件
if exist "%MARK_FILE%" (
    echo 脚本 %SCRIPT_NAME% 已经启动!
    exit /B 1
)

echo 脚本开始运行 > "%MARK_FILE%"
rem 脚本主体内容...

:: 脚本结束时通知守护进程清理 lock 文件
echo 脚本结束 >> "%MARK_FILE%"

goto :eof

:: 清理守护进程脚本 cleanup.bat
:: 守护进程持续监测 lock 文件,当发现文件中有“脚本结束”字样时,删除 lock 文件
:: 并终止自身进程
:cleanup
set MARK_FILE=%1
:loop
timeout /T 1 /NOBREAK > nul
if exist "%MARK_FILE%" (
    for /F "tokens=*" %%i in (%MARK_FILE%) do (
        if "%%i"=="脚本结束" (
            del "%MARK_FILE%"
            exit
        )
    )
)
goto loop

这段代码仅供参考,因为 cleanup.bat 还要判断主进程是否结束,只有主进程结束后才能清理 MARK_FILE,可以和方法二结合,达到更健壮的目的。