自删除批处理文件,用于删除未完全删除且未在Windows 7上退出的目录

时间:2014-05-23 20:01:47

标签: windows batch-file cmd

在卸载时,我运行一个可执行文件来创建一个自删除批处理文件来进行一些目录清理。它总是很好用,并且已经存在多年了。

我遇到了一个需要做类似事情的情况,在安装时做一些清理工作。我有一个不同的.Net控制台应用程序,它创建并运行我从InstallShield 2013生成的setup.exe启动的批处理文件。以下是事件序列:

  1. 安装程序会创建一个目录并提取一些文件,其中一个是setup.exe。
  2. 运行最终运行setup.exe的exe。
  3. Setup.exe执行安装,就在退出之前,我调用LaunchApp来运行我的控制台应用程序DirectoryDe​​lete.exe,并将要删除的目录作为参数。
  4. DirectoryDe​​lete.exe在要删除的目录的父目录中创建一个批处理文件并运行它。
  5. 例如,生成的命令行是:

    DirectoryDe​​lete.exe -dir" C:\ Users \ AUser \ AppData \ Local \ Temp \ STD1234.tmp"

    生成的批处理文件是:

    @echo off  
    :repeatExe  
    del "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\setup.exe"  
    if exist "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\setup.exe" goto repeatExe  
    :repeatDir  
    rmdir "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp" /s /q  
    if exist C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\nul goto repeatDir  
    del %~F0&exit  
    

    所以,基本上批处理文件等待setup.exe完成,然后悄悄地删除目录,然后自己删除。

    然而,正在发生的事情是目录被删除的内容,但目录和批处理文件都没有被删除。看起来批处理文件卡在一个循环中 - 可能会阻塞自己。当我尝试自己删除目录(命令行或资源管理器)时,它说另一个进程正在使用它(批处理文件的cmd.exe)。如果我尝试重新运行批处理文件,它会很忙。如果我杀了cmd.exe,那么我可以手动清理。

    由于这种技术在卸载时运行良好,我很担心为什么它在安装时的清理过程中无效。一切都在提升特权。我最好的猜测是它与上下文有关 - 从setup.exe启动的控制台应用程序。

    非常感谢任何帮助或想法。

    编辑:

    我让批处理文件退出并自行删除,但目录仍然没有被删除。我通过添加几行来修改批处理文件:

    @echo off  
    :repeatExe  
    del "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\setup.exe"  
    if exist "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\setup.exe" goto repeatExe  
    :repeatDir  
    if not exist "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\DeleteDirectory.exe" goto cleaned  
    rmdir "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp" /s /q  
    if exist C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\nul goto repeatDir  
    :cleaned
    rmdir "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp" /s /q  
    del %~F0&exit  
    

    我的想法是寻找另一个我知道的文件。如果它已被删除,那么我知道rmdir做了部分工作。这样我至少可以打破循环并再次删除目录,然后清理并离开。

    我学到的是rmdir失败,因此在原始bat文件中创建了一个无限循环。现在,如果我自己运行批处理文件,即使在安装过程创建的目录上,一切正常....

    对于rmdir / s不起作用将意味着文件正在使用,文件被锁定或权限问题。还有关于工作目录的混淆吗?

1 个答案:

答案 0 :(得分:0)

我弄清楚问题是什么:rmdir / s失败了,因为当前目录设置为我试图删除的目录。显然在卸载操作期间并非如此。

我更改了我的批处理文件以移动到目录DeleteDirectory.exe:

@echo off  
pushd "%~dp0"
:repeatExe  
del "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\setup.exe"  
if exist "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\setup.exe" goto repeatExe  
:repeatDir  
rmdir "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp" /s /q  
if exist C:\Users\AUser\AppData\Local\Temp\STD1234.tmp\nul goto repeatDir  
del %~F0&exit  

现在工作正常。