How to remove directory recursively?

RemoveDirectory(); Removes only empty directory, but how to remove directories that have files inside?
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
This clears directory from files, but what I do next?
Well, call RemoveDirectory(). What else? :P

http://msdn.microsoft.com/en-us/library/aa365488%28VS.85%29.aspx
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
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
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
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;
}
Your code makes exe crash.

My current list.txt D:\trash\rain\*
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
now it deletes \rain too but i want clear D:\trash\rain with out deleting rain
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
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.
Ow.

Well you could just make the folder again, but... thats not what you want i guess =P
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
'pint' is a spam bot - who do I complain to?
any ideas how to make it clear directory given instead of removing it
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;
}
Great thanks guestgulkan.
Topic archived. No new replies allowed.