batch-processing - 识别批处理文件的运行实例

标签 batch-processing batch-file

这些对我不起作用。

任何帮助肯定纠正下面的四个例子?

EXAMPLE01 只是回显“继续”,即使我打开了三个 CMD.exe。

--------- 示例 01 ------------

@echo off 
wmic process where name="cmd.exe" | find "cmd.exe" /c
SET ERRORLEVEL=value if "%value%" GTR 1 ( 
    ECHO This batch is not first  
    ECHO quitting ...
    )
if "%value%" LSS 2 ECHO continue

我在示例 02 中收到“意外 i 错误”消息!

----------- 示例 02 -------

@echo off
FOR /F "usebackq tokens=2" %i IN (`tasklist ^| findstr /r /b "cmd.exe"`)
   DO taskkill /pid %%i

我在示例 03 中收到“是第一个”消息,即使打开了三个 CMD.exe!

----------- 示例 03 -------

 @echo off
    wmic process where name="cmd.exe" | find "cmd.exe" /c
    if "%errorlevel%" LEQ 1 echo CMD is first
    if "%errorlevel%" GTR 1 echo CMD is already running

也有可能我在工作时无法访问 Wmic 命令,因此,在示例 04 中找到了另一种可能性……但无济于事。

----------- 示例 04 -------

@echo off
Tasklist /FI "IMAGENAME eq cmd.exe" 2>NUL | find /I /N "cmd.exe">NUL
if "%ERRORLEVEL%"==0 do (goto Use) else (goto Cont)
:Cont
ECHO Only one instance running
pause

:Use
echo Application running already. Close this window

亲切的问候, 马莱克

最佳答案

wmz 发现了 OP 代码中的一些错误,并且还有一个很好的建议是使用锁文件进行并发控制。

下面是一个强大的批处理解决方案,它使用锁定文件来防止批处理文件的多个实例同时运行。它使用临时锁定文件进行并发控制。锁定文件的存在并不会阻止脚本运行。仅当另一个进程对锁定文件具有排他锁时,该脚本才会失败。如果脚本在不删除锁定文件的情况下崩溃或被终止,这一点很重要。运行脚本的下一个进程仍然会成功,因为文件不再被锁定。

此脚本假定脚本安装在本地驱动器上。它只允许整台机器使用一个实例。有很多变化可以控制允许的并发量。例如,将 %USERNAME% 并入锁定文件名将允许网络环境中的每个用户一个实例。在名称中加入 %COMPUTERNAME% 将允许网络环境中的每台机器有一个实例。

@echo off
setlocal

:: save parameters to variables here as needed
set "param1=%~1"
:: etc.

:: Redirect an unused file handle for an entire code block to a lock file.
:: The batch file will maintain a lock on the file until the code block
:: ends or until the process is killed. The main code is called from
:: within the block. The first process to run this script will succeed.
:: Subsequent attempts will fail as long as the original is still running.
set "started="
9>"%~f0.lock" (
  set "started=1"
  call :start
)
if defined started (
    del "%~f0.lock" >nul 2>nul
) else (
    echo Process aborted: "%~f0" is already running
)
exit /b

:start
:: The main program appears below
:: All this script does is PAUSE so we can see what happens if
:: the script is run multiple times simultaneously.
pause
exit /b


编辑

错误消息“该进程无法访问该文件,因为它正被另一个进程使用。”可以通过将 stderr 输出重定向到外部 block 中的 nul 来抑制。

2>nul (
  9>"%~f0.lock" (
    set "started=1"
    call :start
  )
)

上面的问题是主程序的所有错误消息也会被抑制。这可以通过以下方式解决:首先将 stderr 的当前定义保存到另一个未使用的文件句柄,然后添加另一个将 stderr 重定向回保存的文件句柄的内部 block 。

8>&2 2>nul (
  9>"%~f0.lock" (
    2>&8 (
      set "started=1"
      call :start
    )
  )
)

关于batch-processing - 识别批处理文件的运行实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11619416/

相关文章:

windows - 使用 CMD 比较文件

java - Spring-Batch:将对象写入固定长度的行?

java - bat文件不在Java中执行

windows - 批处理以列出不包含特定文件的文件夹

windows-7 - 在程序关闭时使用批处理文件更改墙纸。可能的?

java - 如何识别 ItemWriter 中的异常(由 ItemReader、readItem 方法发生)

batch-processing - 如何将我的 Rexx 程序作为批处理作业运行?

kubernetes - Kubernetes 上的批处理

batch-file - 如何将命令发送到通过批处理命令行运行的 EXE?

python - 从 Python 2 返回的区别——版本检查和 Python 3