2011-08-06 120 views
6

假设我有一个批处理文件来执行长时间构建,并在最后创建一个EXE。如果我在开始构建之前忘记关闭应用程序,则无法重新创建EXE时链接阶段失败。检测文件是否在批处理文件中打开

我想检查EXE是否在构建的开始处打开。我尝试将EXE文件重命名为自身,但虽然这会导致访问被拒绝,但重命名命令(作为内部命令)不会设置%ErrorLevel%。

什么是检查将%ErrorLevel%设置为非零值的打开文件的非破坏性方法?

回答

6

重命名方法不适用于我(在Windows XP SP3上测试过)。我开始了一个任意的应用程序,并试图将其重命名为自己。没有错误,没有任何影响。

然而,这种方法没有工作:

COPY /B app.exe+NUL app.exe 

当应用程序正在运行,这个命令我产生一个错误信息。并且,当应用程序未挂入时,不仅该命令保留了文件的内容,而且还使修改时间戳保持不变。

如果我是你,所以,我可能会以这种方式使用此命令(在批处理脚本的开始,像你说的):

COPY /B app.exe+NUL app.exe >NUL || (GOTO :EOF) 

||使用者将控制命令如果前面的命令失败(提高了错误级别的值),它旁边的/ block。因此,如果COPY失败(如果该文件已打开,则该命令将终止该脚本)。

错误消息将被保留(因为这些消息通常发送到所谓的标准错误设备,并且不会被重定向>NUL丢弃,而其他非错误消息通常会发送到标准输出,所以可以被压制为>NUL)并作为脚本过早终止的解释。但是,如果你想显示自己的信息,而不是,你可以尝试这样的事:

COPY /B app.exe+NUL app.exe >NUL 2>NUL || (ECHO Target file inaccessible& GOTO :EOF) 

虽然>NUL皮无论是发送到标准输出,2>NUL做为标准错误一样。

+0

谢谢@Andriy。是的,那是有效的。如果涉及的可执行文件很大,我可能需要一点时间。另一种我想到的方式是编写一个2行的delphi实用程序,它尝试将文件重命名为随机名称,如果成功则将其重命名为,如果不能,则返回零退出代码。 – rossmcm

1
@echo off 

:start 
ren filename filename  // rename file to same name 
if errorlevel 1 goto errorline 
echo command successfull file is not in use anymore 
goto end 
:errorline 
echo Rename wasnt possible, file is in use try again in 5seconds 
timeout /T 5 
goto :start 
:end 
exit 

重命名文件同名,如果可能的脚本跳到结束伟驰退出代码,otherwize它产生错误代码1,并跳转到errorline,5秒超时后跳转到:启动和脚本启动从开始。

+0

任何解释这是什么?如何调用它或使用它?你能把它翻译成英文吗? – Abel

1

找到一个更好的办法:

:start 
timeout /T 5 

if exist %1 (
2>nul (
    >> %1 (call) 
) && (goto ende) || (goto start)) else (exit) 


:ende 
YourCode 

这将在5秒后检查每个“正在使用的文件”,如果它会重新开始。如果没有,它会变成你可以做你的下一个选项

相关问题