首页 > 解决方案 > 在命令提示符下使用 DEL 批处理文件命令删除后文件去哪了?

问题描述

我有一个简单的批处理文件,它运行并在运行后自行删除。这个应用程序放在桌面上,将使用注册表 RUNONCE 执行。要自行删除它,我在下面使用此命令。

goto 2>nul & del /Q "%APP_PATH%"

与下面的命令不同,上面的命令不会在控制台中打印任何错误。

del /Q "%APP_PATH%"

批处理文件已在桌面中删除。当我们安装我们的内部应用程序(不是恢复应用程序)时,使用命令删除的批处理文件DEL将恢复到之前的位置。我还没有机会检查内部应用程序源代码。通过这个级别的信息,有没有人知道为什么会发生这种奇怪的行为?

标签: windowsbatch-filecmd

解决方案


Windows 命令处理器cmd.exe逐行处理批处理文件。这意味着它打开一个批处理文件,读取下一行,解析它,如果没有更多行要读取,它关闭批处理文件。然后它在解析的行上执行命令。请参阅Windows 命令解释器 (CMD.EXE) 如何解析脚本?

如果此处存在严重语法,Windows 命令处理器将退出批处理文件的处理。此处使用此错误条件处理。

使用以下行创建一个批处理文件:

@echo off
goto
echo Third line!

打开命令提示符并通过键入其完整限定文件名来运行此批处理文件,即驱动器+路径+名称+扩展名用双引号括起来。

cmd.exe由于第二行缺少批处理标签,因此输出以下错误消息。

没有为 GOTO 命令指定批处理标签。

第三行不再执行,cmd.exe因为在执行第二个命令行后退出批处理文件处理,因为这个严重的语法错误,不清楚在cmd.exe哪里继续批处理文件处理。

现在让我们看一下命令行:

goto 2>nul & del /Q "%APP_PATH%"

这是一个命令行,在一行中有两个命令,如我在Single line with multiple commands using Windows batch file上的回答中详细描述的那样。

缺少批处理标签的第一个命令goto导致退出批处理文件处理。在这种情况下,错误消息输出cmd.exe被重定向2>nul到设备NUL以抑制它。但是del /Q "%APP_PATH%"具有已扩展环境变量的第二个命令%APP_PATH%已经在命令队列中。出于这个原因,接下来会执行该命令。

然后cmd.exe甚至不尝试再次打开批处理文件以读取第三行,因为无效命令导致退出批处理文件处理,如果引用批处理文件的名称,goto在这种情况下甚至不再存在。%APP_PATH%

顺便说一句:APP_PATH很奇怪,因为具有完整路径的文件名具有误导性的环境变量名称。

这是一个更好的例子:

首先创建一个Test1.cmd具有以下行名称的批处理文件:

@echo off
echo %~nx0 is calling Test2.cmd.
call "%~dp0Test2.cmd"
echo %~nx0 is processed further.

Test2.cmd使用以下行创建第二个批处理文件:

@echo off
set "BatchFile=%~f0"
echo %~nx0 is deleting itself now.
goto 2>nul & del /A /F "%BatchFile%"

然后从命令提示符窗口中运行Test1.cmd。输出是:

Test1.cmd is calling Test2.cmd.
Test2.cmd is deleting itself now.
Test1.cmd is processed further.

可以看出,通过处理Test2.cmd删除了自己,没有显示任何错误信息。但是在删除本身之后继续处理。cmd.exeTest2.cmdTest1.cmdTest2.cmd

该选项/Q在删除单个文件时并不是真正必需的,并且该文件在运行命令时肯定存在。该选项/A对于删除批处理文件很有用,即使它设置了隐藏属性,否则del不会删除它。/F即使设置了只读属性,该选项对于删除批处理文件也很有用。

另一种命令方法是使用批处理文件中的最后一个命令行,它应该删除自己的命令行:

del /A /F "%~f0" & exit

但它有一个缺点,因为它可以在Test2.cmd使用线条创建时看到:

@echo off
echo %~nx0 is deleting itself now.
del /A /F "%~f0" & exit

Test1.cmd从命令提示符窗口中运行。批处理文件Test2.cmd会自行删除,但命令exit会导致退出cmd.exe打开的命令提示符窗口并处理两个批处理文件。因此,Test1.cmd不会进一步处理,控制台窗口会立即关闭。

/B在 command 之后添加选项exit将导致不退出,但由于 not foundcmd.exe会输出两条错误消息。cmd.exeTest2.cmd

因此,使用goto 2>nul & del /A /F "%~f0"是自删除批处理文件的最佳实践示例。

顺便说一句:顺序或两个命令很重要。的使用del /A /F "%~f0" & goto 2>nul会导致错误消息输出,cmd.exe因为在这种情况下它会尝试再次打开已删除的批处理文件。


推荐阅读