【问题标题】:How to make a batch file delete itself?如何使批处理文件自行删除?
【发布时间】:2013-12-18 05:21:58
【问题描述】:

是否可以让批处理文件自行删除?

我试图让它执行另一个文件来删除它,但这不起作用。

有人知道我是怎么做到的吗?

我正在使用的批处理文件已提升。我的操作系统是 Windows 7 32 位。

【问题讨论】:

    标签: windows batch-file windows-7 delete-file elevated-privileges


    【解决方案1】:

    npocmaka 的回答有效,但它会生成以下错误消息:“找不到批处理文件。”如果控制台窗口在脚本终止,因为消息会以如此快的速度闪烁,没有人会看到它。但是如果脚本终止后控制台保持打开状态是非常不可取的。

    在不显示错误消息的情况下删除文件的技巧是在脚本终止后让另一个隐藏进程删除文件。这可以很容易地使用 START /B 启动删除过程来完成。删除过程的启动和执行需要时间,因此父脚本有机会在删除发生之前彻底终止。

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

    如果您担心 SHIFT 会破坏 %0 值,您可以简单地使用 CALLed 子例程。

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

    2015 年 7 月 16 日更新

    我发现了另一种非常巧妙的方法,可以让批处理脚本自行删除而不会生成任何错误消息。该技术依赖于新发现的 GOTO 行为(由一些俄罗斯人发现),英文描述为 http://www.dostips.com/forum/viewtopic.php?f=3&t=6491

    总之,(GOTO) 2>NUL 的行为类似于EXIT /B,除了它允许在调用者的上下文中执行串联命令!

    所以你只需要

    (goto) 2>nul & del "%~f0"
    

    返回的 ERRORLEVEL 将为 0,因为 DEL 是最后一个命令,它总是清除 ERRORLEVEL。

    如果您需要控制 ERRORLEVEL,则类似

    (goto) 2>nul & del "%~f0" & cmd /c exit /b 10
    

    【讨论】:

    • ISTM 没有括号可以正常工作;即goto 2> nul & …
    • @Scott 我同意。没有括号似乎可以正常工作。我实际上只是创建了一个批处理文件,该文件创建另一个批处理文件,然后在完成所有工作后自行删除!
    • @dbenham 有什么理由相信 goto 周围的括号是必要的,或者省略它们会导致任何问题?
    • @RockPaperLz-MaskitorCasket - 如果没有括号,它应该可以正常工作。我包含它们是为了表明我故意没有包含 GOTO 的目标。
    • @dbenham 感谢您提供更新并说明您选择将它们包含在示例中的原因。非常感谢。
    【解决方案2】:
    ( del /q /f "%~f0" >nul 2>&1 & exit /b 0  )
    

    在脚本末尾设置此项。 (如果使用SHIFT 命令可能不起作用)

    【讨论】:

    • 这可行,但会生成“找不到批处理文件。”错误。请参阅my answer 以获得解决方案。
    • 这使您可以返回(goto) 解决方案不允许的任意错误代码。
    • @vvnurmi - 我已更新 the (goto) solution 以展示如何返回您自己的错误代码。
    【解决方案3】:
    del "%~f0"
    

    可以,但是如果您从之前打开的控制台调用它会出现错误消息(但是可以忽略)。

    【讨论】:

      【解决方案4】:
      del %0
      

      因为文件的最后一行是我找到的最简单的方法。 %0 返回当前正在执行的 .cmd 文件的名称。

      当我第一次尝试时,我以为我会收到“文件正在使用”错误,但到目前为止还没有发生。

      【讨论】:

        【解决方案5】:

        作为对this question 的回答,(被搁置)这批将在运行三遍后自毁。实现这一点的代码压缩在最后 3 行中。它包含above tip from dbenham

        @Echo off
        Rem batch main purpose
        Rem
        Rem
        Set Tok=###&For /f %%C in ('find /C "%Tok%" ^<"%~f0"') Do Set /A Cnt=%%C
        Echo Run-%Cnt%&If %Cnt% Geq 3 (goto) 2>nul & del "%~f0"
        Echo %Tok%>>"%~f0"& Goto :Eof
        

        批处理通过在每次运行后附加一个标记并计算该标记的出现次数来修改自己。如果达到该数字,它会自行删除。

        > Dir /B Kill*
        KillMySelf.cmd
        
        > KillMySelf.cmd
        Run-1
        
        > KillMySelf.cmd
        Run-2
        
        > KillMySelf.cmd
        Run-3
        
        > Dir /B Kill*
        File Not Found
        

        【讨论】:

          【解决方案6】:

          如果在桌面上,您可以使用del (name),否则使用del (path to file ex. del C:\WINDOWS

          P.S 不会产生错误消息

          【讨论】:

            【解决方案7】:

            删除 %0 作为批处理文件的最后一行

            【讨论】:

              【解决方案8】:

              您可以设置延迟以避免竞争条件,这里是 15 秒:

              START /B CMD.EXE /D /C "PING.EXE -n 15 127.0.0.1 && DEL prova.bat"
              

              注意事项

              • CMD.EXE /D 是强制性的,以避免执行自动运行的垃圾软件
              • PING 和 DEL 必须同步执行,所以用引号括起来
              • 我告诉用户如何使用“%~f0”传递批次名称

              【讨论】:

              • 您还可以使用 TIMEOUT 命令使其等待,并使其对普通用户不那么刺耳。您也可以按一个按钮提前结束它。请注意,它仅适用于 Windows 7 及更高版本。
              【解决方案9】:

              如果其他人试图使用 user6811411 的 3 运行然后自毁脚本并且它不起作用。我发现 & 的解释不正确。我的解决方案只是将如下命令分开。

              @Echo off
              Rem batch main purpose
              Rem
              Rem
              Set Tok=###
              For /f %%C in ('find /C "%Tok%" ^<"%~f0"') Do Set /A Cnt=%%C
              Echo Run-%Cnt%
              If %Cnt% Geq 3 (goto) 2>nul & del "%~f0"
              Echo %Tok%>>"%~f0" & Goto :Eof
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-02-25
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多