【问题标题】:Where does the file go after deleting using DEL batch file command in the command prompt?在命令提示符下使用 DEL 批处理文件命令删除后文件去哪了?
【发布时间】:2021-01-11 07:50:50
【问题描述】:

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

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

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

del /Q "%APP_PATH%"

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

【问题讨论】:

  • del 只是删除指向文件的指针,将占用的扇区标记为“空闲”(不像使用资源管理器删除,它将文件移动到回收站)很有可能,您的应用程序不会“恢复”文件,但写入一个新副本。
  • @Stephan 但是从哪里可以得到详细信息来写一个新的?
  • 在 application.exe 或其安装例程中。
  • @Stephan 这个批处理文件是通过注册表运行的 RUNONCE 有区别吗?
  • 成功删除取决于 a) %APP_PATH% 的确切内容,b) 任务工作文件夹的设置以及 c) 进程绑定到的用户的权限根据文件夹。 “娱乐”与此无关(据我所知)。

标签: windows batch-file cmd


【解决方案1】:

Windows 命令处理器cmd.exe 逐行处理批处理文件。这意味着它打开一个批处理文件,读取下一行,解析它,如果没有更多行要读取,它关闭批处理文件。然后它在解析的行上执行命令。见How does the Windows Command Interpreter (CMD.EXE) parse scripts?

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

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

@echo off
goto
echo Third line!

打开command prompt 并通过键入其完整的限定文件名来运行此批处理文件,即驱动器+路径+名称+扩展名括在双引号中。

由于第二行缺少批处理标签,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.

cmd.exe处理Test2.cmd可以看出Test2.cmd删除了自己,没有显示任何错误信息。但Test1.cmd 的处理在Test2.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 不会被进一步处理,控制台窗口会立即关闭。

在命令exit 之后附加选项/B 将导致不退出cmd.exe,但cmd.exe 将输出两条错误消息,因为找不到Test2.cmd

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

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

【讨论】:

  • 我在脚本set APP_PATH=%~f0中设置了变量。
猜你喜欢
  • 2013-05-28
  • 1970-01-01
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-05
  • 1970-01-01
相关资源
最近更新 更多