hi all
I want to write a visual C# programs that delete all files and folders in specific directory but leave the parents directory like
temp file
C:\Users\user\AppData\Local\Temp
MSN cache
C:\Users\user\AppData\Local\Microsoft\Windows Live\Contacts
etc etc...
but I need some help I had read the msdn library
http://msdn.microsoft.com/en-us/library/fxeahc5f.aspx
anyone could help me to write a program like that ?

Recommended Answers

All 29 Replies

Try this link. This one deals with working with files. Use this info to delete the files in the directory you want to keep. Use the other info you got to delete any subdirectories and their files in that directory.

@tinstaafl thanks man actcully I did it after posting that question as first step
here is what i have done

        private void Clear_Click(object sender, EventArgs e)
        {
            File.Delete("C:\\Users\\Samer\\Desktop\\1\\2.txt");
        }

and now i am trying to delete all files in the folder "1" using foreach.. just trying it
if anyone has anyother suggestion ?

here is what come up with... but that will delete the parant folder which named "1"
and I want to delete the contains of the folder "1" not the the folder it self

    private void Clear_Click(object sender, EventArgs e)
    {
        List<DirectoryInfo> FolderToClear = new List<DirectoryInfo>();
        FolderToClear.Add(new DirectoryInfo("C:\\Users\\Samer\\Desktop\\1\\"));

        foreach (DirectoryInfo directory in FolderToClear)
        {
            directory.Delete(true);
        }
    }

ForEach will work. use directory.getfiles to load an array with the fullpaths of all the files in a directory. then pass each string to files.delete

@tinstaafl ummmmm I made a list of directory in the code above as u can see
I think it will work better than array am I right ??
if you have ayn suggestion please Ill be glad to hear it :))

    private void Clear_Click(object sender, EventArgs e)
    {
        List<DirectoryInfo> FolderToClear = new List<DirectoryInfo>();

        // here is a list of files  I want to delete 
        FolderToClear.Add(new DirectoryInfo("path1"));
        FolderToClear.Add(new DirectoryInfo("path2"));
        FolderToClear.Add(new DirectoryInfo("path3"));
        FolderToClear.Add(new DirectoryInfo("path4"));

        foreach (DirectoryInfo directory in FolderToClear)
        {
            directory.Delete(true);
        }
    }

And Any ideas how to deal with the FileNotFoundException ????
anyother exceptions could come into ur mind ?

here is the last update of my code I had add some new ideas like the numbers of deleted files and I am working on The total size of it

and please if anyone could help me with these Issues I had post
how to delete everything that folder "1" contains but leave the folder it self ??
And Any ideas how to deal with the FileNotFoundException ????
anyother exceptions could come into ur mind ?

        public void clear_button()
        {
            try
            {
                int FilesCounter = 0;

                List<DirectoryInfo> FolderToClear = new List<DirectoryInfo>();
                FolderToClear.Add(new DirectoryInfo(@"C:\\Users\\user\\Desktop\\1\\"));

                foreach (DirectoryInfo directory in FolderToClear)
                {               
                    directory.Delete(true);
                    FilesCounter++;
                }


                MessageBox.Show("Done" + "\nDeleted Files Number is " + FilesCounter, "Message",);
                //Application.Exit();
            }
            catch
            {
                throw new FileNotFoundException();
            }
        }

Thanks all & goodnight for me now.....

I looked at the documentation for 'directoryinfo' and it indicates that your code will delete only the directories. I've put together a small routine that will do what you asked:

        private void DeleteContents(string Path)
        {
            string[] DirectoryList = Directory.GetDirectories(Path);
            string[] FileList = Directory.GetFiles(Path);

            foreach (string Fil in FileList)
            {
                File.Delete(Fil);
            }
            foreach ( string Drectory in DirectoryList)
            {
                Directory.Delete(Drectory, true);
            }
            MessageBox.Show("Done\nFiles deleted - " + FileList.Length + "\nDirectories deleted - " + DirectoryList.Length,"Results", MessageBoxButtons.OK);
        }

As for any notfound exceptions, since you're deleting stuff anyway, just catch and ignore. One option if you don't want to use try-catch, you can read the .exist method for file/directory before your delete it. However your reading the directory and deleting the contents right away, there shouldn't be much chance of a file or directory being deleted or renamed before you try and do it.

Here's a try-catch block you can try if you want:

            try
            {
            }
            catch(Exception e)
            {
                if (e.Message.Contains("NotFound")) { }
                else
                    throw (e);
            }

This will ignore anything notfound and thorw anything(i.e. no permission)

@tinstaafl thanks for help first then

for the exception you suggest it do the same as the one did above...

the FileList.Length and DirectoryList.Length it gives an negative values like -5 etc...
so I declared two varabile as the code I show you before and add them to foreach loops
and the give me same result as the one in ur code but NOT negative is it wrong way ?

I nocited that if the flolder "1" has subfolder "2" and this folder contains files it will not be counted with the both way ur way and my way of counting files... ummm anyway u suggest to solve this ??

Thanks for help :)

   public void clear_button()
        {
            try
            {
                int FilesCounter = 0;
                int FoldersCounter = 0;

                string[] DirectoryList = Directory.GetDirectories("C:\\Users\\user\\Desktop\\1");
                string[] FileList = Directory.GetFiles("C:\\Users\\user\\Desktop\\1");

                foreach (string x in FileList)
                {
                    File.Delete(x);
                    FilesCounter++;
                }

                foreach (string y in DirectoryList)
                {
                    Directory.Delete(y, true);
                    FoldersCounter++;
                }

                MessageBox.Show("Done... ^_^\nFiles deleted - " + FileList.Length + "\nDirectories deleted - " + DirectoryList.Length +"\n"+FilesCounter+"\n"+FoldersCounter, "Results", MessageBoxButtons.OK,MessageBoxIcon.Information);
                Application.Exit();
            }
            catch (Exception SJD)
            {
                if (SJD.Message.Contains("NotFound"))
                {
                    MessageBox.Show("File Not Found");
                }
                else
                {
                    throw (SJD);
                }
                //throw new FileNotFoundException();
            }
        }

I made this method that calculate the total size of deleted files but I am getting this error msg

"Property or indexer 'System.IO.FileInfo.Length' cannot be assigned to -- it is read only"

its works fine when I code it in the same method clear_button above but its shows the message box in each loop and I did find away to get out of this problem

        public void File_Size()
        {
            //File Size
            int TotalFileSize;
            DirectoryInfo X = new DirectoryInfo("C:\\Users\\Samer\\Desktop\\1");
            FileInfo[] FileSize = X.GetFiles();
            foreach (FileInfo Finfo in FileSize)
            {
                Finfo.Length = TotalFileSize;
            }
        }

Finfo can only be read. You cannot set it's Length property. I guess you mean to do this:

        public int File_Size()
        {
            int TotalFileSize = 0;
            DirectoryInfo X = new DirectoryInfo("C:\\Users\\Samer\\Desktop\\1");
            FileInfo[] FileSize = X.GetFiles();
            foreach (FileInfo Finfo in FileSize)
            {
                TotalFileSize += Finfo.Length;
            }
            return TotalFileSize;
        }

I don't know how you got negative values on the length property, it should be either 0 or positive integer. Also in your catch routine, your exception wil also catch directorynotfound, if others are going to using this you might want to include that possibility in your message. One way to count all the files and sub directories is to use the directorylist and loop through it and count the files in each directory. You can nest another foreach loop to count the files before you delete the directories.

the whole code in your hands man me too i dont know How I get negative values..
ummmm and yea other may use this code and now I am afriad if I want to add new directories to other program is really not efficient way to add each path for each program/path or I forget to add one of path to all these part of code
for example i want to add new path so i should add the path in

1 DirectoryList
2 FileList
3 to File_Size method

is there is any better ways to do this ??

I am thinking to add a textbox and add path button to allow other to add new paths
is that possible ??
or add feadback button that send an email to my email ...

i dont know any ideas ??

Thanks all for help
thanks pritaeas

I would suggest calling the delete routine with one path at a time. But you can set it up for user input with, A button, a label, and a folderbrowserdialog. in the button click event call the dialog, use the label to display the path, then display a messagebox to confirm, since you'll be making massive deletes. Then either call the delete sub with the path(separate variable or use label.text) as a parameter or have another button to call it and get the path from the label.text. If you really want to do multiple paths at once, storing the paths in a textbox, make it read-only, and using an add button will work, but I would still suggest having the add button call the folderbrowserdialog, as that way you know for certain that you'll be getting valid path strings. You might want an edit button to delete a path from the textbox. and maybe an option(radio button?) to confirm each path before delete or not. and of course the delete paths button.

@tinstaafl thats what ill try to do and you suggest to call the delete routine with one path at a time how cloud i do that ??
at the beganing i made a list so I call it one time but now with the modification and developing the code I cant use list

If you look at the routine I posted originally, it excepts a path variable as string(i.e private void DeleteContents(string Path)). In the subroutine,Path holds the path to the directory you want to empty. In your click event, to call the subroutine use DeleteContents(label1.text). If you still want to use a list, get it set up to do one path at a time. if your list is never, or infrequently changed you can put it into an array and loop through the array in the button click event. If the list changes with each user, or each time the program is called, my previous suggestion with the textbox will work the same way, except textbox already has an array its textbox.lines, and you can loop through it the same way.

@tinstaafl uh ill try it and ill replay back to u
and here is what I have done about adding new path to the code but that code delete the file instantly when I click on the button and it one time use what I actlly want to do is add this path to the code it self so could be use again and again ... got it ??
if yes how is that possible ?

i thnik in ajax where able to something like that but c# I have no idea if that possible

        private void Browse_Click(object sender, EventArgs e)
        {
            OpenFileDialog browseButton = new OpenFileDialog();

            browseButton.InitialDirectory = "c:\\";

            if (browseButton.ShowDialog() == DialogResult.OK)
            {
                DialogResult DR;
                DR = MessageBox.Show("You are going to add " + browseButton.FileName + " path to delete list.\nAre you sure?", "Warning", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
                BrowseTextBox.Text = browseButton.FileName;
                if (DialogResult == DialogResult.OK)
                {
                    // add the path to the code ??
                }
            }
        }

first off you're using the openfiledialog, which will point to a file, which will require parsing it to get the path to the file. If you use the folderbrowserdialog it will point only to the folder path, not requiring any parsing. Here's the way I did it:

            private void button1_Click(object sender, EventArgs e)
            {
                folderBrowserDialog1.RootFolder=Environment.SpecialFolder.MyComputer;
                folderBrowserDialog1.SelectedPath = "C:\\";            
                DialogResult Result= folderBrowserDialog1.ShowDialog();
                if (Result != DialogResult.Cancel)
                {
                    label1.Text = folderBrowserDialog1.SelectedPath;
                    Result= MessageBox.Show("Do you want to delete the contents of theis folder?", "Confirm Delete", MessageBoxButtons.YesNo);
                    if (Result != DialogResult.No)
                    {
                        DeleteContents(label1.Text);
                    }
                    else
                    {
                        label1.text="";
                    }
                }
            }
            private void DeleteContents(string Path)
            {
                string[] DirectoryList = Directory.GetDirectories(Path);
                string[] FileList = Directory.GetFiles(Path);
                foreach (string Fil in FileList)
                {
                    File.Delete(Fil);
                }
                foreach ( string Drectory in DirectoryList)
                {
                    Directory.Delete(Drectory, true);
                }
                MessageBox.Show("Done\nFiles deleted - " + FileList.Length + "\nDirectories deleted - " + DirectoryList.Length,"Results", MessageBoxButtons.OK);
            }               

Did some looking, found how to get total number of files and total number of directories:

int AllFiles = Directory.GetFiles(Path, "*", SearchOption.AllDirectories).Length;
int AllDirs = Directory.GetDirectories(Path, "*", SearchOption.AllDirectories).Length;

this reports exctly the same info you get when the properties for a folder, reports the number of files and folders.

@tinstaafl you are right man your way of browsing is better but there is big mistake when press yes to confirm the deletion it deletes the contains of the folder specified in delete contains method NOT the path specified by user... :D

What method are you referring to? It's calling the subroutine and passing label1.text which contains the folderBrowserDialog1.SelectedPath. I've tested this several times even filling a folder with over 5,000 files and over 500 folders and it worked fine, except for special folders, which is easily caught and handled. You mentioned earlier reusing the path. You can add another button. Use one to set the path and the other to do the delete, which it can get the path from label1.text.

@tinstaafl I really get confused and lost in my code... Thanks for being patient with me

code1

    private void Clear_Click(object sender, EventArgs e)
    {
        List<DirectoryInfo> FolderToClear = new List<DirectoryInfo>();

        // here is a list of files  I want to delete 
        FolderToClear.Add(new DirectoryInfo("path1"));
        FolderToClear.Add(new DirectoryInfo("path2"));
        FolderToClear.Add(new DirectoryInfo("path3"));
        FolderToClear.Add(new DirectoryInfo("path4"));

        foreach (DirectoryInfo directory in FolderToClear)
        {
            directory.Delete(true);
        }
    }

code2

    private void DeleteContents(string Path)
    {
        string[] DirectoryList = Directory.GetDirectories(Path);
        string[] FileList = Directory.GetFiles(Path);

        foreach (string Fil in FileList)
        {
            File.Delete(Fil);
        }
        foreach ( string Drectory in DirectoryList)
        {
            Directory.Delete(Drectory, true);
        }
        MessageBox.Show("Done\nFiles deleted - " + FileList.Length + "\nDirectories deleted - " + DirectoryList.Length,"Results", MessageBoxButtons.OK);
    }

the the fist code will allow me to add as much as I want paths but the second one will not allow me to add paths or I have to create array of string for each path and a new loop for each one... which is something really pian fulll
anyway to use the fist code to delete the contains of the folder NOT the folder and its contain because I just add the path to the FolderToClear and thats done
am I right man ?? or not

Are the paths in code 1, files you want to delete, directories you want to delete, or directories you want to clean out?. If I understand your past messages you want to clean out multiple folders. Making this change to line 13,DeleteContents(directory.FullName);, will clean the directories and files from each directory in your list. If you wanted to go one step further and make it easy to add or delete any path in your list I've put together some modifications, the form as 3 buttons and 1 multiline textbox, which you can pre-load with any standard paths that you want. The first button adds paths to the list. The second one runs the delete sub routine on each path in the list. The thrid one allows you to delete a path from the list, just select the line with the mouse and press the button:

       private void btnAddPath_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.RootFolder=Environment.SpecialFolder.MyComputer;
            folderBrowserDialog1.SelectedPath = "C:\\";
            DialogResult Result= folderBrowserDialog1.ShowDialog();
            if (Result != DialogResult.Cancel)
            {
                textBox1.AppendText(folderBrowserDialog1.SelectedPath + "\n");

            }
        }
        private void btnCleanDirectory_Click(object sender, EventArgs e)
        {
            DialogResult Result = MessageBox.Show("Do you want to delete the contents of all the folders in the list?", "Confirm Delete", MessageBoxButtons.YesNo);
            if (Result == DialogResult.Yes)
            {
                foreach (string line in textBox1.Lines)
                {
                    if (line != "")
                    DeleteContents(line);
                }
            }
        }
        private void DeleteContents(string Path)
        {
            try
            {
                string[] DirectoryList = Directory.GetDirectories(Path);
                string[] FileList = Directory.GetFiles(Path);
                int AllFiles = Directory.GetFiles(Path, "*", SearchOption.AllDirectories).Length;
                int AllDirs = Directory.GetDirectories(Path, "*", SearchOption.AllDirectories).Length;
                foreach (string Fil in FileList)
                {

                    File.Delete(Fil);
                }
                foreach (string Drectory in DirectoryList)
                {


                    Directory.Delete(Drectory, true);
                }
                MessageBox.Show("Done\nFiles deleted - " + AllFiles + "\nDirectories deleted - " + AllDirs, "Results", MessageBoxButtons.OK);

            }
            catch(Exception e)
            {
                if (e.Message.Contains("NotFound")) { }
                else
                    throw (e);
            }
        }

        private void btnEditPaths_Click(object sender, EventArgs e)
        {
            if (textBox1.SelectionLength != 0)
            {
                textBox1.SelectedText = "";
            }
            else 
            {
                MessageBox.Show("Select the line(s) to be deleted");
            }
        }

@tinstaafl yes man I want to clean out multiple folders

first forget about adding new paths to the code or browsing to path and delete it..

Now I want my small program to do the follwing

I have thses paths
Path1
path2
path3
path4.. etc

expamples:
the temp file in here..
C:\Users\user\AppData\Local\Temp
and the cashe files of msn
C:\Users\user\AppData\Local\Microsoft\Windows Live\Contacts

I want to delete eveything in these folders but leaving the parent directory without deleting it

code1 allow me to add all these paths and I can add new paths later..

code2 I can only add one path each time and if i would to add new path I have to make new array and new loop which something not efficient while that very easy in code1 I just add one line to code and thats done...

I perfer to use code1 but the problems that I am facing is

  1. Deleting some files may cause Error when I run the program again after deleting them..
    2.some files are not removable...

so I am trying to avoid these to problems by deleting the contains of folders not the folder it self -there is no need to delete the perant folder-

any modifications to code1 to delete contains of folders not the folder it self??

Finally Thanks alot for your Patient & trying t help me I really appreciate your kindness :)

To save some files put an if statement around line 35, to filter any file patterns you want to save(i.e.if(fil.contains(".cfg"))to save any file containing '.cfg'). To skip a file that can't be deleted, Remove lines 48 to 50. This causes any exceptions to be ignored and the file skipped. To only delete files and not any of the folders, delete lines 37-42 and 28. To delete some folders and save others do the same as with the files, around line 35, but maybe check for whether the folder is empty, rather than pattern matching.

@tinstaafl dear friend I finally come up with this code... Hope you will give your opinion with it then I am working on some exception
try this code if you can suggest to me ways of handleing these exceptions like

1.access dined

2.The process cannot access the file 'FXSAPIDebugLogFile.txt' because it is being used by another process.

public void keepTheseFolders(DirectoryInfo dirInfo)
        {
            DeleteFolder(new DirectoryInfo(@"C:\Users\user\AppData\Local\Temp"), false);
            DeleteFolder(new DirectoryInfo(@"C:\Users\user\AppData\Local\Windows Live"), false);
            DeleteFolder(new DirectoryInfo(@"C:\Users\user\AppData\Local\Microsoft\Windows Live\Contacts"), false);

        }

        public void DeleteFolder(DirectoryInfo dirInfo, bool DeleteDirectory)
        {
            //Check for subDirectory
            foreach (DirectoryInfo di in dirInfo.GetDirectories())
            {
                //Call itself to delete the sub directory
                DeleteFolder(di, true);
            }
            //Delete Files in Directory
            foreach (FileInfo fi in dirInfo.GetFiles())
            {
                fi.Delete();
            }
            //Finally Delete Empty Directory if optioned
            if (DeleteDirectory)
            {
                dirInfo.Delete();
            }
        }

Thanks alot for that and btw I nocted that this code will work only on my current PC but if I changed this PC this PC wont work because I spcified paths which could be deffernt on other pc like the user accont name its deffernet from pc to another one
so How could I get over this problem ??

try this code if you can suggest to me ways of handleing these exceptions like

1.access dined

2.The process cannot access the file 'FXSAPIDebugLogFile.txt' because it is being used by another process.

To handle this use the try-catch but leave catch empty. This way the files that you don't have permission to delete will remain.

Thanks alot for that and btw I nocted that this code will work only on my current PC but if I changed this PC this PC wont work because I spcified paths which could be deffernt on other pc like the user accont name its deffernet from pc to another one
so How could I get over this problem ??

use the folderbrowserdialog control and add each path to a listbox, then you can read them and pass them to the delete routine.

@tinstaafl works fine for the exception

while i am searching I found the path.gettempfiles() method that get the windows temp files path so I can I avoid the problems of spcifid paths but this for the windows temp files anything that could works for other files?

and in the temp files there are files that have .tmp extension those file did not deleted by the code I post why ?

while i am searching I found the path.gettempfiles() method that get the windows temp files path so I can I avoid the problems of spcifid paths but this for the windows temp files anything that could works for other files?

If other software uses the default temp folder their temp files will be in there. If not it'll depend on each software where the temp files are put.

and in the temp files there are files that have .tmp extension those file did not deleted by the code I post why ?

Many times the software that put the files there will lock them until they're done. The exception trick I showed you will cause these files to simply be ignored, and your code will continue to the next file.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.