通过程序管道输出时如何避免“正在由另一个进程使用”错误?

通过程序管道输出时如何避免“正在由另一个进程使用”错误?

在 Windows 环境中,如果从不同的 CMD 环境调用,用于处理管道输出的可执行程序是否保证是唯一的任务?

例如,假设 script1.cmd 包含此行:

echo "some logging information" | my_pipe_program >> logfile1.txt

另外,script2.cmd 包含以下行:

echo "some other information" | my_pipe_program >> logfile2.txt

如果 script1 和 script2 恰好同时运行,Windows 是否会调用 my_pipe_program.exe 的单独实例?

我偶尔会遇到错误,命令脚本失败,错误信息为“进程无法访问文件,因为该文件正在被另一个进程使用”。此错误总是发生在通过 my_pipe_program.exe 进行管道传输的行之后。
它会导致 CMD 脚本立即停止在该位置,使 CMD 窗口保持打开状态。

冲突可能与 my_pipe_program.exe 有关,也可能与 logfile2.txt 有关。程序 my_pipe_program.exe 用于多个 CMD 文件,这些文件可能同时运行。日志文件是 CMD 文件所独有的,因此它不太可能是罪魁祸首,除非 Windows 在 CMD 文件存在后无法关闭它。有什么方法可以诊断问题并修复错误吗?

相关问题 - 有什么方法可以捕获和处理“...正在被另一个进程使用”错误并防止 CMD 文件中止?

答案1

听起来问题可能出在这里,EXE以及它如何处理在同一台机器上同时在内存中运行的调用。启用此级别的高级日志记录以捕获详细信息或堆栈跟踪,同时模拟从同一台机器在内存中同时运行,就像问题发生时一样,这可能是最准确的答案为什么它正在这样做。

请参阅我的回答(超级用户) 前几天在 SuperUser 上,如果CMDBAT文件是喜欢某个名字。

您可以结合类似这样的方法,使用这些批处理文件名检查是否有某个程序已经运行了一段时间,然后终止程序,但您必须查看其他选项,WMIC看看是否有计时器等。如果这适用于您的情况,那么修复EXE该级别的逻辑并捕获错误并结束可能是最好的选择,如果您在该级别进行控制的话。


其他想法

一个简单的解决方案可能是在批处理 CMD 文件启动时创建一个锁文件,以便EXE从同一台机器启动该脚本的所有脚本首先检查锁文件是否存在,如果存在,则结束该脚本(或者可能暂停几分钟然后再次检查等)。

您可以结束脚本 [ GOTO locked] 或暂停几秒钟,然后转到该例程 [ GOTO lockedrecheck] 并再次检查其他进程是否已完成,如果这对您来说足够了,则删除该文件。

如果锁文件不存在,它会创建该文件,然后运行该进程,完成后删除锁文件,以便其他进程可以运行(下面的示例)。

您还可以将其添加到2<&1日志文件的末尾以获取更多详细信息(如果EXE允许以这种方式捕获则无法捕获)(下面的示例脚本逻辑)。

锁定文件示例(结束或暂停并重新检查)

<ABOVE LOGIC>
<ABOVE LOGIC>
<ABOVE LOGIC>
<ABOVE LOGIC>

:SetLockFile
::SET check for, and create lock file to ensure concurrent runs aren't possible
SET lockfile=\\server\share\lockfiles\my_pipe_program.lck
IF EXIST %lockfile% GOTO locked
::IF EXIST %lockfile% GOTO lockedrecheck 
ECHO This file is locked until current %~nx0 script ends or finishes using the EXE >> %lockfile%

ECHO "some logging information" | my_pipe_program >> %logfile% 2<&1

<More Logic>
<More Logic>
<More Logic>
<More Logic>

:end
ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> %logfile%
ECHO End: %date% at %time%                       >> %logfile%
ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> %logfile%
DEL /Q /F "%lockfile%"
ENDLOCAL
GOTO EOF

:locked
:: Come here to end the script since the lock file does exist
ECHO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>> %logfile%
ECHO LOCKED FILE: %~nx0 - %date% at %time%: FILE IS IN USE AND LOCKED                             >> %logfile%
ECHO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>> %logfile%
ENDLOCAL
GOTO EOF

:lockedrecheck
:: Come here to Pause the script with a loopback ping to nul for 3 minutes or roughly 180 seconds
PING 127.0.0.1 -n 180 > nul
GOTO :SetLockFile

2<&1例子

echo "some logging information" | my_pipe_program >> logfile1.txt 2<&1

相关内容