Self-deleting batch file to delete a directory not fully deleting and not exiting on Windows 7 - windows

At uninstall time I run an executable to create a self-deleting batch file to do some directory cleanup. It always works great and has been for years.
I have run into a case where I need to do something similar to do some cleanup at install time. I have a different .Net console app that creates and runs a batch file that I am launching from setup.exe generated by InstallShield 2013. Here is the sequence of events:
Installer creates a directory and extracts some files, one of which is setup.exe.
An exe is run that ultimately runs setup.exe.
Setup.exe does the installation and just before exit I call LaunchApp to run my console app, DirectoryDelete.exe, with the directory to delete as an argument.
DirectoryDelete.exe creates a batch file in the parent directory of the directory to delete and runs it.
For example the resulting command line is:
DirectoryDelete.exe -dir "C:\Users\AUser\AppData\Local\Temp\STD1234.tmp"
The resulting batch file is:
#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
So, basically the batch file waits on setup.exe to finish, then quietly deletes the directory, then itself.
However, what is happening is the contents of the directory get deleted, but neither the directory nor the batch file get deleted. It looks like the batch file is stuck in a loop - likely blocking itself. When I try to delete the directory myself (command line or explorer), it says another process is using it (the cmd.exe of the batch file). If I try to re-run the batch file, it is busy. If I kill the cmd.exe, then I can manually clean up.
Since this technique works so well at uninstall time, I am pretty confused about why it is not working during my cleanup at install time. Everything is running with elevated privileges. My best guess is it has to do with the context - the console application being launched from setup.exe.
Any help or ideas would be greatly appreciated.
EDIT:
I got the batch file to exit and delete itself, but the directory still did not get deleted. I modified the batch file by adding a few of lines:
#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
My idea was to look for another file I knew was there. If it had been deleted, then I know the rmdir did part of its work. That way I could at least break the loop and take another shot at removing the directory, then clean up and get out.
What I learned there is that the rmdir is failing, thus creating an infinite loop in the original bat file. Now, if I run the batch file myself, even on a directory created by the install process, everything works fine....
For rmdir /s to not work would mean a file is in use, a file is locked or a permissions problem. Could there also be confusion about working directory?

I figured out what the problem was: The rmdir /s was failing because the current directory was set to the directory I was trying to delete. Apparently that is not the case during the uninstall operation.
I changed my batch file to move up to the directory DeleteDirectory.exe is launched from:
#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
Works fine now.

Related

Why can't I delete the contents of the 'INetCache' folder from the command prompt?

I'm using Windows 10 and need to update a batch file to clear the contents of folder at "C:\Users\myUserName\AppData\Local\Microsoft\Windows\INetCache". This is the folder that holds cache for Internet Explorer.
I would have thought the command was simply as follows:
DEL /S /F /Q C:\Users\myUserName\AppData\Local\Microsoft\Windows\INetCache\*
This command executes without issue, but when I look at the contents of the folder via Windows Explorer, it still has stuff in it. I say "stuff" because while it looks like a bunch of files, they don't behave like typical files. For instance, I cannot see these files when when I use "dir" on the command prompt no matter which flags I utilize. And when I examine the properties of these files, there is barely any information associated with them.
Why isn't my DEL command clearing out these files?
Screenshot of "files" still present in my INetCache folder
Screenshot of the properties of one of these files
I found that using the "rmdir" command instead of the "del" command resolved my issue.
rmdir "C:\Users\myUserName\AppData\Local\Microsoft\Windows\INetCache" /s /q
open txt and save .bat file
DEL /S /F /Q C:\Users\%username%\AppData\Local\Microsoft\Windows\INetCache\*
pause

How to delete a directory from within that same directory with a batch file?

call :deleteSelf&exit /b
:deleteSelf
start "" /D "C:\Windows" /MIN cmd /c RD /S /Q "C:\Windows\test"&&exit /b
This is the code I use. Batch file running it sits within C:\Windows\test
The file is successfully deleted, along with any other files in the directory, but not the directory itself. Does anyone know some way to solve this issue? I'm rather stumped.
You will need, at least, to
leave the current batch file so it is not open
ensure your current active directory is not the one you want to remove
so, if you follow the already pointed dbenham's approach for leaving the current batch file you could use something like
((goto) 2>nul & cd "%~dp0\.." && rmdir /s /q "%~dp0")
That is,
the (goto) will generate an error that will leave current batch file execution
we change the current active directory to the parent of the folder where the batch file is stored
it the active directory has been changed, we try to remove the folder that holds the batch file
Of course, if there is another process/file locking the folder you will not be able to remove it.
surely it's not as easy as adding the following line to your batch file:
cd c:\
rd c:\windows\test

call command for bat script not working

Essentially I have two .bat scripts that work just fine individually, however I wanted to combine the two scripts into one action as i have it assigned to a hotkey and want all of this with one press of a key, not two but am having problems because the scripts are in different directories.
Below are my two scripts:
BLAH-Script.bat
RE4_UHD_BLAH_Tool.exe -p
DEL /F /S /Q /A "F:\r101\r101_09.AEV"
and the second script:
UDAS_TOOL.bat:
DEL /F /S /Q /A "F:\st1\rl01.udas"
ping -n 1 localhost
DEL /F /S /Q /A "F:\UDAS Tool\r101.udas"
UDAS_Tool.exe -p
Now, both of these work great on their own because each of the scripts calls on an .exe that is in the same DIR as the script that calls them, but trying to get them into one .bat file has not worked using the CALL function because one of the scripts exists in an outside directory.
I have tried to make a new .bat script that would execute both bat scripts in one:
call "F:\pack\BLAH-Script.bat"
ping -n 1 localhost
call "F:\pack\UDAS\UDAS_TOOL.bat"
However this does not work.The files are not packaged by the exe tools as intended.
To try and figure out the problem I added pause command between scripts:
call "F:\pack\BLAH-Script.bat"
pause
call "F:\pack\UDAS_TOOL.bat"
This command allowed me to read the output before the window was closed and yielded the culprit. In the first script I am getting the following error:
F:\UD - r101-->RE4_UHD_BLAH_Tool.exe -p
'RE4_UHD_BLAH_Tool.exe' is not recognized as an internal or external command,
operable program or batch file.
I believe what is happening it that each file works fine if run in its own directory because they are in the same DIR as the .exe they are calling, but the first .bat file will not execute because the third bat file ( the one that is that is calling the first & second) is not in the same DIR as the first.
I have tried:
CD /D "F:\pack"
call "F:\pack\BLAH-Script.bat"
pause
CD /D "F:\pack"
call "F:\pack\UDAS\UDAS_TOOL.bat"
with the same error.
How do I get the directories sorted out ?
In theory, you could simply fully-qualify the executable path, or make sure that the executables are located on the path.
However, some programs assume that the executable is in the current directory, and expect that configuration files, etc. are similarly in that directory, so what I'd do is
in each batch, after the initialisation ceremony (#echo off/setlocal...) add a
pushd "actualexcutablelocation"
and ensure that on exit from the batch,
popd
is executed to restore to the original directory.
pushd switches current directory to the nominated directory until a popd is executed to return to the original.

How do I make a batch file delete it's own directory?

Okay, I apologize that I am very new at this, but I am trying to make my batch file delete it's own directory after it has been launched. This is how my folders are arranged:
Folder1
delete.bat
My goal is to make "delete.bat" delete "Folder1" after "delete.bat" has been launched. So here's my code:
rd /s /q %~dp0..\Folder1
This seems like it would work but it only deletes the contents of "Folder1" rather than the whole directory itself. What am I doing wrong?
Some thoughts...
%~dp0 gets the drive and path of the batch file, so you don't need to include ..\Folder1.
What you have should work. If it's not removing the folder itself, it means that it's locked, probably because cmd's current folder is Folder1. (That's a likely guess, but it's not the only reason it might be locked.) If it is cmd, you'll have to call the batch file from another folder, outside of Folder1.
While what you have will work, it will result in a funny error when resuming the non-existent batch file: The system cannot find the path specified. You can avoid that in the solution below.
One good solution: start /b "" cmd /c rd /s /q "%~dp0"
This creates a new process to remove the folder (and everything in it, including the batch file itself). Be careful. =)
From the corresponding MSDN link for rd:
You cannot use rmdir to delete the current directory. You must first change to a different directory (not a subdirectory of the current directory) and then use rmdir with a path.
I guess this is what's going wrong in your case since the batch file is located within the directory that you're trying to delete.
My implementation is effectively the same as Soja's, plus the info from dbenham's comment. I have added a 2-sec delay, to ensure there are no timing issues, even though I believe the error when the .bat file is deleting itself is harmless.
#echo off
:: Do the work
...your command here...
:: In order to delete the current dir we are running from (and all subdirs), none of them can be the
:: current working directory of any running process. Therefore, we are setting our own CWD to something
:: else, so it will be inherited by the below cmd.exe.
cd /d %temp%
:: The countdown is there to allow this batch file to exit, so it can then be deleted safely.
set DelayedSelfDeleteCommand="timeout /t 2 >NUL && rmdir /s /q "%~dp0""
:: Start a separate process (without waiting for it), to execute the command
start "" /b cmd.exe /C %DelayedSelfDeleteCommand%
Well I think it cannot be done (at least as normal user)
start /b "" cmd /c rd /s "%~dp0"
deletes folder but only with right permissions I think
start /b "" cmd /c rmdir /s "C:/folder"
This has the same result
del /s /q "C:\Temp\folder\*"
rmdir /s /q "C:\Temp\folder"
del %0
only way as for batch files is to use vbs script or autohotkey (send !{Space} // send e // send p formula) or hack it, you can delete only file used and content of folder but not working directory due to specification of cmd. Any other language would have no problem with it cuz it in RAM memory.
I recommend this way to do it (as for normal users):
in your bat file add
copy C:\urpath\deleteafter.bat C:\Temp\deleteafter.bat
start "" autohotkey.exe "X:\patchto\deletebatchfile.ahk"
deletebatchfile.ahk
sleep 2000
Run, C:\Temp\deleteafter.bat, C:\Temp\
deleteafter.bat
rmdir /s /q "C:\Temp\batfileworkingpath"
sleep 3
del %0

Write a batch file to do call another batch file and install a program

I am having trouble with a batch file. I have 2 files the first batch file runs and it creates the directory and copies the files needed. It appears to call the second batch file correctly because it opens the instructions.txt but then it stops. I will be running the first batch file from a CD and then the dbinstall.bat from the C:\testing folder.
this is my setup.bat
#echo off
md "C:\testing"
xcopy *.* C:\testing
CALL "C:\testing\dbinstall.bat"
Which in turns should call and run this
REM ***PLEASE REPLACE %DWVerFileName.exe WITH THE PROPER VERSION OF THE EXE FILE***
REM ***MAKE SURE THE 7z FILE INCLUDES THE CUSTOMER NAME AND THEN CHANGE %filename%.7z TO THE FILE NAME***
CALL "C:\testing\Instructions.rtf"
start /b /wait "C:\testing\7z423.exe"
SET AppExePath="%ProgramFiles(x86)%\7-zip\7z.exe"
IF NOT EXIST %AppExePath% SET AppExePath="%ProgramFiles%\7-zip\7z.exe"
%AppExePath% e database.7z
start /b /wait "setup.exe"
SQLCMD -E -S touch -Q "RESTORE DATABASE testing FROM DISK='C:\testing\database.bak'"
I am stuck and any help would be appreciated. Thanks
Since we have no idea of what "it stops" means, or where "it stops", I'd guess
CALL "C:\testing\Instructions.rtf"
should be
start "instructions" "C:\testing\Instructions.rtf"
which would then invoke whatever program is associated with .rtf, no doubt dislaying the instructions and keeping the displaying mechanism open while the 7z423 executable runs.

Resources