如何判断我的批处理文件是否正在运行?

Fri*_*ave 8 windows powershell vbscript batch-file

我有一个从 AT 命令运行的批处理脚本,并且可能会多次运行。当它启动时,我需要它检测它是否已经在运行,如果是,立即退出(第二个)。

  1. 它必须健壮,并处理脚本意外退出(即,我无法在进入时设置标志并在退出时清除它)
  2. 它必须在远程桌面会话中运行
  3. 我一直在使用 Powershell v2 的 XP,但如果我不能在批处理/powershell 或 vbs 中执行,请不要介意编写一个小 exe
  4. 脚本必须最小化运行,所以我用 Start "NAME" /MIN %COMSPEC% /C "MyScript.bat" 启动它
  5. 其他 cmd 窗口可能已打开,因此我需要检查正在运行的脚本
  6. 批处理脚本以 SYSTEM 用户身份运行,但我无法使用任何 WMI

我正在使用 PowerShell Get-Process 查看 MainWindowTitle,但是当远程连接到计算机时这不起作用,因为脚本可能正在运行,但未显示在此远程连接实例中。在这种情况下,Get-Process 可以看到 cmd 进程,但 MainWindowTitle 是空白的。

我试过 Get-Process 并查看了扩展的 StartInfo.EnvironmentVariables 属性,但看不到如何创建 env var 以便它出现在属性中。

我想过在启动命令中使用/WAIT,然后AT会一直打开直到它完成,但是包含AT的脚本没有被最小化

有任何想法吗?

dbe*_*ham 7

我相信锁定文件是最简单可靠的解决方案。诀窍是确保您正在运行的批处理进程在文件上保持独占写锁定,直到它终止。这个系统的美妙之处在于无论批处理终止的原因是什么,Windows 都会释放锁。

拥有锁定文件后,您需要一种方法来检测文件当前是否被锁定。如果给定的文件或目录被锁定(由任何进程使用),我在如何检查命令行中描述了如何执行此操作

我已经使用这种原始但有效的技术通过 Windows 批处理完成了一些相当复杂的任务:

您不清楚批处理文件驻留在何处——在远程机器上,还是在本地机器上,或者您是否可能同时在多台机器上运行脚本,但每台机器只有一个活动进程。

如果批处理脚本在远程机器上,并且您的进程对该脚本具有写权限,那么您可以将批处理文件本身用作锁定文件!您只需要调用 :subroutine,同时使用追加模式将未使用的文件句柄重定向到批处理脚本。如果另一个进程已经拥有锁,则 CALL 将失败。当脚本终止时(不管它如何终止),锁会自动释放。

我的脚本文件

@echo off
:: Note - this extra call is to avoid a bug with %~f0 when the script
::        is executed with quotes around the script name.
call :getLock
exit /b

:getLock
:: The CALL will fail if another process already has a write lock on the script
call :main 9>>"%~f0"
exit /b

:main
:: Body of your script goes here. Only one process can ever get here
:: at a time. The lock will be released upon return from this routine,
:: or when the script terminates for any reason
exit /b
Run Code Online (Sandbox Code Playgroud)

如果您的脚本与进程在不同的机器上,但您一次只能在一台机器上运行该进程,那么我认为上述方法仍然有效。

也许更好的选择是在每台远程机器上建立一个专用的锁定文件,与批处理脚本分开。然后,您可以根据需要在任意数量的远程计算机上运行该进程。