How to remove directory recursively?

Aug 8, 2010 at 8:53pm
RemoveDirectory(); Removes only empty directory, but how to remove directories that have files inside?
Aug 8, 2010 at 9:03pm
Delete the files first. Use FindFirstFile, FindNextFile to enumerate the files in the directory and DeleteFile to delete them.

Useful example:
http://msdn.microsoft.com/en-us/library/aa365200%28VS.85%29.aspx
Aug 8, 2010 at 10:13pm
This clears directory from files, but what I do next?
Aug 8, 2010 at 10:16pm
Well, call RemoveDirectory(). What else? :P

http://msdn.microsoft.com/en-us/library/aa365488%28VS.85%29.aspx
Aug 9, 2010 at 8:57am
RemoveDirectory needs empty directory but all these directiries have files and directories inside. How to go in to all flders alnd list all contents?

since i dont know how many folders aren in C:\X i can't write fixed loop
Last edited on Aug 9, 2010 at 9:04am
Aug 9, 2010 at 9:08am
Make a function that takes a directory, opens it and checks it for files. If it comes across a file, remove it, if it comes across a directory, recursively call the function for that directory. That's really all.
Last edited on Aug 9, 2010 at 9:08am
Aug 10, 2010 at 1:00pm
I made function but does anyone know why it doesn't delet empty directories? (look at DirectoryRecursive)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// del2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <string>
#include <iostream>
#include "Shlwapi.h"


using namespace std;

//bool DirectoryRecursive(char * path = new char[261])
bool DirectoryRecursive(char path[261])
{
	WIN32_FIND_DATA FindFileData;
    HANDLE hFind;
	DWORD Attributes;
	strcat(path,"\\*");
	//path[strlen(path)] = '*';

	hFind = FindFirstFile(path, &FindFileData);
	//printf("---Recursive: %s\n",path);
			do{
				if (strcmp(FindFileData.cFileName, ".") != 0 && strcmp(FindFileData.cFileName, "..") != 0){
				//Str append Example
				char str[MAX_PATH];
				strcpy (str,path);
				str[strlen(path)-1] = '\0';
				strcat (str,FindFileData.cFileName);
				//_tprintf (TEXT("---File Found: %s\n"),str);
				Attributes = GetFileAttributes(str);
				//_tprintf (TEXT("---File Attributes: %d\n"),Attributes);
				if (Attributes & FILE_ATTRIBUTE_DIRECTORY)
				{
				DirectoryRecursive(str);
				//str[strlen(str)] = '\\';
				str[strlen(path)-1] = '\0';
				printf("--Rem: '%s'\n",str);
				RemoveDirectory(str);
				}
				else
				{
				remove( str );
				}
				}
			}while(FindNextFile(hFind, &FindFileData));
	return true;
}

int main()
{
	system("cls");
   WIN32_FIND_DATA FindFileData;
   HANDLE hFind;

   //Read list file
   FILE *filein;
   long lSize;
   char * buffer;
   size_t result;
   DWORD Attributes;
   //Get path to list.txt
   	 char szFileName[MAX_PATH];
     HINSTANCE hInstance = GetModuleHandle(NULL);
     GetModuleFileName(hInstance, szFileName, MAX_PATH);
	 PathRemoveFileSpec(szFileName);
	 PathAppend(szFileName,"\\list.txt");
	 //Open file
   filein = fopen(szFileName, "r");
   //if (filein==NULL) {fputs ("File error",stderr); exit (1);}

    // obtain file size:
    fseek (filein , 0 , SEEK_END);
    lSize = ftell (filein);
    rewind (filein);

    // allocate memory to contain the whole file:
    buffer = (char*) malloc ((sizeof(char)*lSize)+1);

	// copy the file into the buffer:
    result = fread (buffer,1,lSize,filein);
	buffer[result] = '\0'; // make extra byte nul
	/*//Print some info
    printf ("%s\n",buffer);// list.txt
	printf ("%s\n",szFileName);//Path
    fclose(filein);
	*/

	//token apc
	char *token;
	token = strtok(buffer,"\r\n");
	   while( token != NULL )
       {
           // While there are tokens in "string"
           printf( "%s\n", token );

		   //List files
			hFind = FindFirstFile(token, &FindFileData);
			do{
				if (strcmp(FindFileData.cFileName, ".") != 0 && strcmp(FindFileData.cFileName, "..") != 0){
				//Str append Example
				char str[MAX_PATH];
				strcpy (str,token);
				str[strlen(token)-1] = '\0';
				strcat (str,FindFileData.cFileName);
				//_tprintf (TEXT("File Found: %s\n"),str);
				Attributes = GetFileAttributes(str);
				if (Attributes & FILE_ATTRIBUTE_DIRECTORY)
				{
				 //is directory
				DirectoryRecursive(str);
				str[strlen(token)-1] = '\0';
				printf("Rem: '%s'\n",str);
				RemoveDirectory(str);
				}
				else
				{
				remove( str );
				//not directory
				}
				}
			}while(FindNextFile(hFind, &FindFileData));
			FindClose(hFind);

           // Get next token: 
           token = strtok( NULL,"\r\n"); // C4996
       }
	free(buffer);
return	0;
}


output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
D:\trash\rain\*
--Rem: 'D:\trash\rain\Application Data\Microsoft\Credentials\'
--Rem: 'D:\trash\rain\Application Data\Microsoft\'
--Rem: 'D:\trash\rain\Application Data\Microsoft\'
--Rem: 'D:\trash\rain\Application Data\Microsoft\SystemCertificates\My\'
--Rem: 'D:\trash\rain\Application Data\Microsoft\SystemCertificates\My\'
--Rem: 'D:\trash\rain\Application Data\Microsoft\SystemCertificates\My\'
--Rem: 'D:\trash\rain\Application Data\Microsoft\SystemCertificates\'
--Rem: 'D:\trash\rain\Application Data\Microsoft\'
--Rem: 'D:\trash\rain\Application Data\'
Rem: 'D:\trash\rain\'
Rem: 'D:\trash\rain\'
Rem: 'D:\trash\rain\'
Rem: 'D:\trash\rain\'
--Rem: 'D:\trash\rain\Local Settings\Application Data\Microsoft\Credentials\'
--Rem: 'D:\trash\rain\Local Settings\Application Data\Microsoft\'
--Rem: 'D:\trash\rain\Local Settings\Application Data\Microsoft\'
--Rem: 'D:\trash\rain\Local Settings\Application Data\'
--Rem: 'D:\trash\rain\Local Settings\'
--Rem: 'D:\trash\rain\Local Settings\History\'
--Rem: 'D:\trash\rain\Local Settings\'
--Rem: 'D:\trash\rain\Local Settings\'
--Rem: 'D:\trash\rain\Local Settings\Temporary Internet Files\Content.IE5\'
--Rem: 'D:\trash\rain\Local Settings\Temporary Internet Files\Content.IE5\'
--Rem: 'D:\trash\rain\Local Settings\Temporary Internet Files\Content.IE5\'
--Rem: 'D:\trash\rain\Local Settings\Temporary Internet Files\Content.IE5\'
--Rem: 'D:\trash\rain\Local Settings\Temporary Internet Files\'
--Rem: 'D:\trash\rain\Local Settings\'
Rem: 'D:\trash\rain\'
Rem: 'D:\trash\rain\'
Rem: 'D:\trash\rain\'
Rem: 'D:\trash\rain\'
--Rem: 'D:\trash\rain\Start Menu\Programs\Accessories\'
--Rem: 'D:\trash\rain\Start Menu\Programs\Accessories\'
--Rem: 'D:\trash\rain\Start Menu\Programs\'
--Rem: 'D:\trash\rain\Start Menu\Programs\'
--Rem: 'D:\trash\rain\Start Menu\'
Rem: 'D:\trash\rain\'
Rem: 'D:\trash\rain\'

C:\Users\rain> 
Last edited on Aug 10, 2010 at 1:51pm
Aug 10, 2010 at 7:52pm
For this I assumed each entry in the list.txt file would be the full directory
path you want to delete (without any trailing \) . For example

D:\trash\rain
D:\trash\rain\Local Settings\History


I'll leave any final tidying up for you to do.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <string>
#include <iostream>
#include "Shlwapi.h"


using namespace std;

//bool DirectoryRecursive(char * path = new char[261])
bool DirectoryRecursive(char *token)
{
    WIN32_FIND_DATA FindFileData;
    HANDLE hFind;
    DWORD Attributes;  
    char str[MAX_PATH];
    
    strcpy (str,token); 
    strcat (str,"\\*.*");


    //List files
    hFind = FindFirstFile(str, &FindFileData);
    do{
        if (strcmp(FindFileData.cFileName, ".") != 0 && strcmp(FindFileData.cFileName, "..") != 0)
        {
            //Str append Example
            strcpy (str, token);
            strcat(str,"\\");
            strcat (str,FindFileData.cFileName);
            //_tprintf (TEXT("File Found: %s\n"),str);
            Attributes = GetFileAttributes(str);
            if (Attributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                //is directory
                DirectoryRecursive(str);
            }
            else
            {
                remove( str );
                //not directory
            }
        }
    }while(FindNextFile(hFind, &FindFileData));
    FindClose(hFind);
    
    RemoveDirectory(token);
	return true;
}

int main()
{
	system("cls");
   WIN32_FIND_DATA FindFileData;
   HANDLE hFind;

   //Read list file
   FILE *filein;
   long lSize;
   char * buffer;
   size_t result;
   DWORD Attributes;
   //Get path to list.txt
   	 char szFileName[MAX_PATH];
     HINSTANCE hInstance = GetModuleHandle(NULL);
     GetModuleFileName(hInstance, szFileName, MAX_PATH);
	 PathRemoveFileSpec(szFileName);
	 PathAppend(szFileName,"\\list.txt");
	 //Open file
   filein = fopen(szFileName, "r");
   //if (filein==NULL) {fputs ("File error",stderr); exit (1);}

    // obtain file size:
    fseek (filein , 0 , SEEK_END);
    lSize = ftell (filein);
    rewind (filein);

    // allocate memory to contain the whole file:
    buffer = (char*) malloc ((sizeof(char)*lSize)+1);

	// copy the file into the buffer:
    result = fread (buffer,1,lSize,filein);
	buffer[result] = '\0'; // make extra byte nul
	/*//Print some info
    printf ("%s\n",buffer);// list.txt
	printf ("%s\n",szFileName);//Path
    fclose(filein);
	*/

	//token apc
	char *token;
	token = strtok(buffer,"\r\n");

	   while( token != NULL )
       {
           // While there are tokens in "string"
           //char FullDir[MAX_PATH];
           printf( "%s\n", token );

            DirectoryRecursive(token);

           // Get next token: 
           token = strtok( NULL,"\r\n"); 
       }
	free(buffer);
return	0;
}
Aug 10, 2010 at 11:30pm
Your code makes exe crash.

My current list.txt D:\trash\rain\*
Aug 10, 2010 at 11:49pm
Like I said, take it and tidy it up.
I did not use a final \ on the directory name in the list.txt file.
So my list.txt file looked like D:\trash\rain
Aug 11, 2010 at 9:08am
now it deletes \rain too but i want clear D:\trash\rain with out deleting rain
Aug 11, 2010 at 9:25am
Can you actually delete a directory, and keep the files it contains?
What happens to the files, how do you access them? Thats awesome o.o

By the way;
http://msdn.microsoft.com/en-us/library/bb762164(v=VS.85).aspx
Last edited on Aug 11, 2010 at 9:27am
Aug 11, 2010 at 12:04pm
Gah you probably did read what i wrote, I don't want delete given directory, I want to cleat that directory.

Clear means you delete all files and folders from that directory but don't toch directory itself.
Aug 11, 2010 at 12:07pm
Ow.

Well you could just make the folder again, but... thats not what you want i guess =P
Aug 11, 2010 at 12:17pm
remaking folder will create folder with wrong owner/attributes/permissions. If i recreate it from another user, that other user might become folder owner thatway, which means original user wont have some access/permissions anymore. because owner on now user who created folder....
Last edited on Aug 11, 2010 at 12:18pm
Aug 11, 2010 at 1:32pm
'pint' is a spam bot - who do I complain to?
Aug 11, 2010 at 5:26pm
any ideas how to make it clear directory given instead of removing it
Aug 11, 2010 at 5:47pm
Yes.
((it would have been nice if you had made that point clear to start with)).

If I was given the code above and told fix it quickly on pain of death , this is what I would do...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <string>
#include <iostream>
#include "Shlwapi.h"


using namespace std;

//bool DirectoryRecursive(char * path = new char[261])
bool DirectoryRecursive(char *token, char* originalName)//<<=============*******
{
    WIN32_FIND_DATA FindFileData;
    HANDLE hFind;
    DWORD Attributes;  
    char str[MAX_PATH];
    
    strcpy (str,token); 
    strcat (str,"\\*.*");


    //List files
    hFind = FindFirstFile(str, &FindFileData);
    do{
        if (strcmp(FindFileData.cFileName, ".") != 0 && strcmp(FindFileData.cFileName, "..") != 0)
        {
            //Str append Example
            strcpy (str, token);
            strcat(str,"\\");
            strcat (str,FindFileData.cFileName);
            //_tprintf (TEXT("File Found: %s\n"),str);
            Attributes = GetFileAttributes(str);
            if (Attributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                //is directory
                DirectoryRecursive(str, originalName);//<<=====================*******
            }
            else
            {
                remove( str );
                //not directory
            }
        }
    }while(FindNextFile(hFind, &FindFileData));
    FindClose(hFind);
    
    if(strcmp ( token, originalName))//<<===================*****
    {
        RemoveDirectory(token);
    }
	return true;
}

int main()
{
	system("cls");
   WIN32_FIND_DATA FindFileData;
   HANDLE hFind;

   //Read list file
   FILE *filein;
   long lSize;
   char * buffer;
   size_t result;
   DWORD Attributes;
   //Get path to list.txt
   	 char szFileName[MAX_PATH];
     HINSTANCE hInstance = GetModuleHandle(NULL);
     GetModuleFileName(hInstance, szFileName, MAX_PATH);
	 PathRemoveFileSpec(szFileName);
	 PathAppend(szFileName,"\\list.txt");
	 //Open file
   filein = fopen(szFileName, "r");
   //if (filein==NULL) {fputs ("File error",stderr); exit (1);}

    // obtain file size:
    fseek (filein , 0 , SEEK_END);
    lSize = ftell (filein);
    rewind (filein);

    // allocate memory to contain the whole file:
    buffer = (char*) malloc ((sizeof(char)*lSize)+1);

	// copy the file into the buffer:
    result = fread (buffer,1,lSize,filein);
	buffer[result] = '\0'; // make extra byte nul
	/*//Print some info
    printf ("%s\n",buffer);// list.txt
	printf ("%s\n",szFileName);//Path
    fclose(filein);
	*/

	//token apc
	char *token;
	token = strtok(buffer,"\r\n");

	   while( token != NULL )
       {
           // While there are tokens in "string"
           //char FullDir[MAX_PATH];
           printf( "%s\n", token );

            DirectoryRecursive(token, token);//<<=========================*************

           // Get next token: 
           token = strtok( NULL,"\r\n"); 
       }
	free(buffer);
return	0;
}
Aug 13, 2010 at 5:06pm
Great thanks guestgulkan.
Topic archived. No new replies allowed.