如何防止两次运行相同的批处理文件以只允许一个实例?

Nim*_*oud 7 windows batch command-line

我需要检测批处理文件是否已经在运行。

在批处理中,我只是循环并重复执行一些任务。有时循环无法完成。我在预定的时间运行批处理文件。当它运行时,它应该检查以前的实例是否存在并且是健康的。如果它不存在,它应该启动一个新实例。如果存在的实例不健康/过时,则新实例应终止/取消旧进程。

几个理论:

  1. 如何检测批处理文件中的先前实例?身份证之类的可以给吗?
  2. 我可以使用脉冲机制来判断批次是否健康;即,全局变量、新创建的虚拟文件、虚拟文件中的时间戳等。
  3. 我可以检测到一种“超时”,如果最后一个脉冲已过期,则允许一个新实例...

是的,我都希望将它们放在批处理文件中 - 而不是 Windows 应用程序 - 我认为对于一个批处理文件上瘾者并将这个问题视为挑战的人来说并不难!

sur*_*asb 6

从批处理文件的角度来看,这相当困难,主要是因为没有保证批处理文件可以跨进程检测实例的方法。

IMO,我认为您使用了错误的工具。虽然,是的,这是一个挑战,但更重要的问题是“它有效吗?”

我在预定的时间运行批处理文件。

这告诉我您应该使用调度程序,例如 Task Scheduler。任务计划程序将保证您的文件只有一个实例,即使它正在另一个用户上运行。

例如,如果您每 30 分钟运行一次任务,则将任务配置为运行 30 分钟。然后将“如果任务已经在运行”设置为“不创建新实例”。或者您必须选择“杀死旧的”、“运行另一个实例”或“在旧的完成后立即开始新任务”。

对于 Vista 及更高版本:http : //technet.microsoft.com/en-us/library/cc748993.aspx#BKMK_cmd
对于 Xp 及更高版本:http : //technet.microsoft.com/en-us/library/bb490996.aspx

具有挑战性的方法是创建状态。

  1. 您的批处理文件进入执行
  2. 你的批处理文件循环
  3. 您的批处理文件结束

你可以在 %allusersprofile% 中创建一个任意文件,就像>>Startmybatchfile.txt echo 1每个州一样,然后检查它是否存在。它还有助于解决问题。但是最后不要删除文件。只需将其更改为结束状态即可。这样就可以确定您的批处理文件是否真正完成并且不再运行。

我不会使用全局变量,因为它需要管理员权限才能运行。

您也可以使用 %temp% 变量,但它会因用户而异。如果您是单登录用户机器,我想这不是问题。


Nim*_*oud 6

这是我最新和最受信任的脚本:

:init
set "started="
2>nul (
 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
    @ping localhost > nul
)

exit /b




:start
cd /d %~dp0
:: REST OF THE SCRIPT
Run Code Online (Sandbox Code Playgroud)

  • 这个脚本中发生了什么?我们可以在多个批处理脚本中使用它吗? (2认同)