Following the Perl mantra of TMTOWTDI – we had a question come up about how to recursively delete a folder’s contents – without deleting the folder itself – using MSBuild.
There are several solutions, but if you have a lot of crud to delete, one of the faster ways is to create a target which has the following calls:
<exec command="dir /ad /b c:\Temp > files.txt"> files.txt"/> </exec><exec command='for /f "Tokens=*" %%i in (files.txt) do rd /s/q "C:\Temp\%%i"'> <delete files="files.txt"></delete></exec>
This spits out all of the subfolders to a temporary text file, then deletes them by looping over them and calling rd. The reason you have to do it this way is that if you just use the for loop without the Tokens=* line, it won’t find directories with spaces in the name, as it, by default, only reads in the first space delimited token.
The reason it has to be to calls is that the “dir /ad /b c:\Temp” call has to be in single-quotes in the for command, but the Tokens=* has to be in double quotes. Since one of those is already taken because we are in an XML attribute, you need to break it into two separate calls.
Another way would be to break the commands into two seperate properties, and then exec that:
<propertygroup> <dir_list>dir /ad /b c:\Temp</dir_list> <del_command>for /f "Tokens=*" %%i in ('$(dir_list)') do rd /s/q "C:\Temp\%%i"</del_command> </propertygroup>
<target name="DeleteTemp"> <exec command="$(del_command)"> </exec></target>
Cory what about
<ItemGroup;>
<SettingsFiles; Include=”$(ProgramFiles)\App\Settings\**”/>
</ItemGroup>
<Target; Name=”DeleteAppSettingsFiles”>
<Delete; Files=”@(SettingsFiles)” />
</Target>
or use the CleanFolder task in the Microsoft SDC Tasks Library: http://www.codeplex.com/sdctasks
Using that ‘DeleteAppSettingsFiles’ as is currently has two problems. 1. it will not delete read only files, 2. It will not delete the folders, only files.
The CleanFolder task provides an easy mechanism to do this.
Very usefull!
tks
I use that in my site , ok?
This post has messed up formatting.
Thanks! Fixed.
hello great blog yea nice job It sounds like you’re creating problems yourself by trying to solve this issue instead of looking at why their is a problem in the first place.
Hi, found this useful!
You can get it to work in a single exec task by using single quotes for the entire exec command and encoding single quotes inside, or viceversa. That is you can write it as follows:
<Exec Command=’for /f “Tokens=*” %%i in (%27dir /ad /b “$(FolderToClean)”%27) do rd /s/q “$(FolderToClean)\%%i”‘ />
[hope it reads well once published]
Besides, if the folder also contains files, and you need to get rid of them, as it was my case, an entire CleanFolder target can be written this way:
<Target Name=”CleanFolder” >
<ItemGroup>
<ToDelete Include=”$(FolderToClean)\*.*” />
</ItemGroup>
<Delete Files=”@(ToDelete)” />
<Exec Command=’for /f “Tokens=*” %%i in (%27dir /ad /b “$(FolderToClean)”%27) do rd /s/q “$(FolderToClean)\%%i”‘ />
</Target>
Cheers,