批处理文件是否知道自己的名称并能够删除自身?

5

在我的脚本中,我希望能够删除自身的批处理文件。这需要脚本知道自己的名称,然后使用该名称来删除自己。这种操作是否可行?

5个回答

12

现有的答案都没有提供一种干净的方法让批处理文件删除自身并退出,而不会显示任何错误消息。

只需包含del "%~f0"即可删除脚本,但这也会导致一个丑陋的"无法找到批处理文件。"错误消息。

如果脚本关闭父CMD进程(控制台窗口)是可以接受的,那么以下内容可以正常工作而不会出现任何错误消息:

del "%~f0"&exit

但是如果你希望脚本在不关闭父CMD进程且不显示任何错误信息的情况下删除自身并退出,则会变得有些复杂。

方法1:启动第二个进程,在同一控制台窗口内运行以执行删除操作。EXIT /B 可能不是必需的,但我加入它是为了最大化批处理脚本在STARTed进程尝试删除文件之前关闭的可能性。

start /b "" cmd /c del "%~f0"&exit /b

方法2:创建并转移到另一个临时批处理文件,该文件会删除自身以及调用者,但不使用CALL,并将stderr重定向到nul。

>"%~f0.bat" echo del "%~f0" "%~f0.bat"
2>nul "%~f0.bat"

3
如果我没记错,%0将是调用批处理文件的路径。

我很好奇,当批处理文件(或任何程序)调用另一个批处理文件时会发生什么...第二个批处理文件中的%0是什么? - st0le
我得试一下,但我猜测问题可能出在调用批处理文件中提供的路径上。 - JoshD
不,这是当前的批处理文件。 - ubiquibacon
所以,我理解的是,如果A.bat调用B.bat,%0就是“B.bat”,对吗?那是我的猜测,虽然我可能没有表述清楚。 - JoshD
%0 总是调用当前批处理文件的命令。 - peterchen
"%0" 可能也是被调用子程序的名称,这取决于它出现的位置。但是,无论在子程序内部还是在 CD 或 PUSHD 之后,"%f0" 都将始终是脚本的完整路径。 - dbenham

2

测试并且工作正常:

del %0
exit

1
可能更好的做法是:del "%~f0" & exit /b。"%~f0" 可以处理从不同目录运行批处理文件和路径中的空格。将两个命令放在一行上可以避免原始形式中有时会出现的“找不到文件”错误,如果 exit 所在的行在执行 del 之前没有缓冲。最后,/b 只退出批处理文件,而不是关闭整个控制台。 - atzz
@atzz - 但是使用exit /b而不是exit会导致一个丑陋的“找不到批处理文件”的错误消息。 - dbenham
@dbenham - 你是正确的。(有趣的是,我不记得以前收到过这个消息;cmd的行为在这些年里改变了吗?还是我的记忆出了问题?)但在我的书中,这比直接关闭控制台要好得多。 - atzz
1
@atzz - 同意 :-) 请参考我的回答中的方法,可以干净地删除而不会出现错误信息。 - dbenham

1

%0 给出了从批处理文件启动的目录到相对路径。因此,如果您调用它

mybats\delyourself.bat tango roger

%0将包含mybats\delyourself.bat

del % 0 适用于您没有更改当前目录的情况。

%~f0扩展到文件的完整路径。


2
不需要使用 SET path_to_bat=%~f0,因为 %~f0 始终 给出当前正在运行的批处理脚本的完整路径,即使在调用的子例程中使用或者自启动以来执行了 CD 或 PUSHD。 - dbenham
当然!我修复了它,不知道为什么我认为它是必要的。我已经更新了回复。 - peterchen

-1
对我来说很重要的是,在退出批处理文件后,我没有错误级别1。我找到了一个适合并简单的解决方案: DeleteMyself.cmd:
START CMD /C DEL DeleteMyself.cmd

测试批处理文件DeleteMyself.cmd是否返回错误级别0。TestDeleteMyself.cmd

call DeleteMyself.cmd
echo Errorlevel: %errorLevel%

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接