Temp files are not deleting - c#

Hi i am actually creating a program to delete all the temp files and folders when an event is triggered. so for that i am using the following code but its not working and throwing an exception
And also for this i am using the code
private void tempfiles_Click(object sender, EventArgs e)
{
if(tempcheck.Checked)
{
string tempPath = System.IO.Path.GetTempPath();
System.IO.DirectoryInfo di = new DirectoryInfo(tempPath);
try
{
foreach (FileInfo file in di.GetFiles())
{
file.Delete();
}
foreach (DirectoryInfo dir in di.GetDirectories())
{
dir.Delete(true);
}
}
catch(Exception env)
{
MessageBox.Show("Please close all the applications and try \n" + env);
}
}
else
{
MessageBox.Show("Please check the checkbox");
}
}
Here i want to delete the folders and files without any exception but in java i use method like fileonclose().

If files are being used by another program, you will not be able to delete them. You should put your try...catch statement inside each for loop. That way you can continue trying to delete files even if one attempt fails.
To make your program more useful, you can keep track of which files were not deleted and create a log or open a window to show the file names to the user.

Related

How do I give my code permission to delete files

I got my code which delete some files, Its kinda weird because its not throwing me any errors.
Essentially whats happening is that, its not deleting any files in the folder(not sure why) I've tried giving it permission to delete Only-Read files but that didnt work.
I've tried debugging but its not showing me anything.
And I understand that it cannot delete files that are being used somewhere else, I've tried deleting a few files manually and that worked, not sure why my code is not doing it automatically though, because if it hits an error it should move on the the next file right?
(This mainly applies to .rar files but also with some folders)
private void Clear_Click(object sender, EventArgs e)
{
string tempPath = Path.GetTempPath();
DirectoryInfo di = new DirectoryInfo(tempPath);
foreach (DirectoryInfo dir in di.GetDirectories())
{
try
{
dir.Delete(true);
}
catch (Exception)
{
// Log error.
continue;
}
}
//-----------------------------------------------------------------------------------------------------
//foreach (FileInfo file in di.GetFiles())
foreach (FileInfo file in di.GetFiles())
{
try
{
file.Delete();
}
catch (Exception)
{
// Log error.
continue;
}
}
//-----------------------------------------------------------------------------------------------------
// string[] extentionList = new[] { "*.jpg", "*.rar", "*.bmp", "*.gif" };
//Delete RAR Files
foreach (FileInfo file in di.GetFiles("*.rar"))
{
try
{
file.Delete();
}
catch
{
//log error I tried running it without the "Continue;" but it still wouldnt log me an error.
continue;
}
}

Can not delete files from Recent folder

I am writing a Software that can delete Temporary files, Prefetch data, files in Recent folder and so on. My problem is I can delete files from Temp folder successfully, but when I try for Recent folder, an exception is thrown, "Access to path...is denied".
PS: According to some other questions, I have set File attributes to normal, but still no luck. Please help me on this issue. For your better understand, I put some code here:
public Boolean CleanRecentData()
{
isAllClean = true;
String SysRecentPath = System.Environment.GetEnvironmentVariable("USERPROFILE") + "\\Recent";
DirectoryInfo SysRecDir = new DirectoryInfo(SysRecentPath);
File.SetAttributes(SysRecentPath, FileAttributes.Normal);
foreach (FileInfo fi in SysRecDir.GetFiles()) //Access Denied
//Exception is thrown here
{
try
{
fi.Delete();
}
catch (Exception ex)
{
recentLogLines.AppendLine(ex.Message);
isAllClean = false;
}
}
foreach (DirectoryInfo dir in SysRecDir.GetDirectories())
{
try
{
dir.Delete(true);
}
catch (Exception ex)
{
recentLogLines.AppendLine(ex.Message);
isAllClean = false;
}
}
return isAllClean;
}
Are you able to access the Recent folder via Windows Explorer?
You could go ahead and change the permissions in your system, but NOT in your users systems.
Therefore you could handle this exception condition in two ways.
You need to check if you have file access before accessing, using FileIOPermission but this might be redundant and wasteful if you are doing it on too many files.
Just try to open the file and put your effort into a good exception handler if it fails
Reference

File.Delete Access to the path is denied

My console application program is creating some runtime files while it is working so what I want to do is delete all of these files on the application startup. I have tried this:
public static void Empty(string targetDir)
{
var directory = new DirectoryInfo(targetDir);
if (!directory.Exists) return;
foreach (var file in directory.GetFiles()) file.Delete();
foreach (var subDirectory in directory.GetDirectories()) subDirectory.Delete(true);
}
...just to look for all the files/folders in the given path (which is in a subdirectory in the program execution path) then delete them. However, I get the following exception:
Access to the path 'file' is denied.
I tried to run the program as administrator with no luck; However, I want a solution that works without using administrator privileges.
Notes :
The file is not running in another application.
The file is not in a protected folder.
The file can be deleted manually with no problems and that's why i
am here.
I got this error and found that it was because my test files were readonly. Changed this and I can now use fileinfo to delete them no worries.
if (File.Exists(filePath))
{
File.SetAttributes(filePath, FileAttributes.Normal);
File.Delete(filePath);
}
You say that the files are not open in another application, but it must be open within your application:
//Create some directories to delete
Directory.CreateDirectory("C:/Temp/DeleteMe");
Directory.CreateDirectory("C:/Temp/DeleteMe/DeleteMe");
File.Create("C:/Temp/DeleteMe/DeleteMeFile");//FileStream still open!!
//Delete the files
var directory = new DirectoryInfo("C:/Temp/DeleteMe");
if (!directory.Exists) return;
foreach (FileInfo file in directory.GetFiles())
{
file.Delete();
}
foreach (DirectoryInfo dir in directory.GetDirectories())
{
dir.Delete(true);
}
Make sure you dispose the file stream when you create the file
//Create some directories to delete
Directory.CreateDirectory("C:/Temp/DeleteMe");
Directory.CreateDirectory("C:/Temp/DeleteMe/DeleteMe");
using (File.Create("C:/Temp/DeleteMe/DeleteMeFile")) { }
//Delete the files
var directory = new DirectoryInfo("C:/Temp/DeleteMe");
if (!directory.Exists) return;
foreach (FileInfo file in directory.GetFiles())
{
file.Delete();
}
foreach (DirectoryInfo dir in directory.GetDirectories())
{
dir.Delete(true);
}
Try using the Microsoft.VisualBasic.FileIO.FileSystem methods as it has a handy DeleteDirectory method, I had access troubles awhile ago and this was the fix for my problem.
var directory = new DirectoryInfo(targetDir);
if (directory.Exists)
{
Microsoft.VisualBasic.FileIO.FileSystem.DeleteDirectory(targetDir, Microsoft.VisualBasic.FileIO.DeleteDirectoryOption.DeleteAllContents);
}
Using Windows API MoveFileEx might be a potential solution with a parameter MOVEFILE_DELAY_UNTIL_REBOOT to remove the file only after reboot.
Please check http://msdn.microsoft.com/en-us/library/aa365240%28v=vs.85%29.aspx.

How to delete files while Traversing folder tree

I am not sure if I am doing this correctly or if my logic is correct.
I am trying to go down a folder structure delete files older than a certain number of days, this part I have correctly implemented, delete empty folders.
Can all this be done in one loop?
Where do I do the folder delete?
I want to delete empty folders up to 3 or 4 level down.
private static void TraverseTree(System.IO.DirectoryInfo folder, double days)
{
Stack<string> dirs = new Stack<string>();
if (!folder.Exists)
throw new ArgumentException();
dirs.Push(folder.FullName);
while (dirs.Count > 0)
{
string currentDir = dirs.Pop();
string[] subDirs;
try
{
subDirs = System.IO.Directory.GetDirectories(currentDir);
}
// An UnauthorizedAccessException exception will be thrown if we do not have
// discovery permission on a folder or file. It may or may not be acceptable
// to ignore the exception and continue enumerating the remaining files and
// folders. It is also possible (but unlikely) that a DirectoryNotFound exception
// will be raised. This will happen if currentDir has been deleted by
// another application or thread after our call to Directory.Exists. The
// choice of which exceptions to catch depends entirely on the specific task
// you are intending to perform and also on how much you know with certainty
// about the systems on which this code will run.
catch (UnauthorizedAccessException e)
{
Console.WriteLine(e.Message);
continue;
}
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
continue;
}
string[] files = null;
try
{
files = System.IO.Directory.GetFiles(currentDir);
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine(e.Message);
continue;
}
catch (System.IO.DirectoryNotFoundException e)
{
Console.WriteLine(e.Message);
continue;
}
// Perform the required action on each file here.
// Modify this block to perform your required task.
foreach (string file in files)
{
try
{
// Perform whatever action is required in your scenario.
System.IO.FileInfo fi = new System.IO.FileInfo(file);
Console.WriteLine("{0}: {1}, {2}", fi.Name, fi.Length, fi.CreationTime);
// Delete old files
if (fi.LastWriteTime < DateTime.Now.AddDays(-days))
fi.Delete();
}
catch (System.IO.FileNotFoundException e)
{
// If file was deleted by a separate application
// or thread since the call to TraverseTree()
// then just continue.
Console.WriteLine(e.Message);
continue;
}
}
// Push the subdirectories onto the stack for traversal.
// This could also be done before handing the files.
foreach (string str in subDirs)
dirs.Push(str);
}
}
Code is from MSDN.
A recursive approach would probably be cleaner.
private static void DeleteOldFilesAndFolders(string path)
{
foreach (string directory in System.IO.Directory.GetDirectories(path))
{
DeleteOldFilesAndFolders(directory);
// If the directory is empty and old, delete it here.
}
foreach (string file in System.IO.Directory.GetFiles(path))
{
// Check the file's age and delete it if it's old.
}
}
Something that I notice about your code is that the dozens of lines of "mechanism" for walking the tree structure completely overwhelms the two lines of code that actually do the work. That makes it hard to read, understand, change, debug and maintain this code.
Here's what I would do instead.
You have only three high-level operations in your program: (1) get all the files, (2) filter to find the ones to delete, (3) delete each file. So write a program which does each of those in one statement.
For the first operation, I would factor out the mechanism above into its own function: a function which implements, say, IEnumerable, and all it does is keeps on yielding out information about files. It doesn't do anything with them; its only purpose is to keep spitting out file infos.
Once you have that mechanism then you can start writing queries on top of that sequence to attain the second operation. The third operation then follows directly from the second.
In short, the main line of your program should look something like this:
var allFiles = TraverseFolder(folder);
var filesToDelete = from file in allFiles where IsOld(file) select file;
foreach(var fileToDelete in filesToDelete) Delete(fileToDelete);
Is that clear?
There is almost the same question here:
How to delete all files and folders in a directory?
This is delete by name, but you could check other properties.
Here is a more general solution to the problem which gives you a file system walker implemented non-recursively as IEnumerable.
for which your solution can probably be implemented as:
List<string> directoriesToDelete = new List<string>();
DirectoryWalker walker = new DirectoryWalker(#"C:\pathToSource\src",
dir => {
if (Directory.GetFileSystemEntries(dir).Length == 0) {
directoriesToDelete.Add(dir);
return false;
}
return true;
},
file => {
if (FileIsTooOld(file)) {
return true;
}
return false;
}
);
foreach (string file in walker)
File.Delete(file);
foreach (string dir in directoriesToDelete)
Directory.Delete(dir);
I enhanced John's solution, implementing missing code, error handling and checks:
/* Given a directory path and a datetime,
* recursively delete all files and directories contained in such directory
* (given directory included) that are younger than the given date.
*/
private bool DeleteDirectoryTree(string dir, DateTime keepFilesYoungerThan)
{
//checks
if (String.IsNullOrEmpty(dir) || !Directory.Exists(dir))
return false;
//recurse on children directories
foreach (string childDir in Directory.GetDirectories(dir))
DeleteDirectoryTree(childDir, keepFilesYoungerThan);
//loop on children files
foreach (string file in Directory.GetFiles(dir))
{
//calculate file datetime
DateTime fileDT = new DateTime(Math.Max(File.GetCreationTime(file).Ticks, File.GetLastWriteTime(file).Ticks));
//if file is old, delete it
if (fileDT <= keepFilesYoungerThan)
try
{
File.Delete(file);
Log("Deleted file " + file);
}
catch (Exception e)
{
LogError("Could not delete file " + file + ", cause: " + e.Message);
}
}
//if this directory is empty, delete it
if (!Directory.EnumerateFileSystemEntries(dir).Any())
try
{
Directory.Delete(dir);
Log("Deleted directory " + dir);
}
catch (Exception e)
{
LogError("Could not delete directory " + dir + ", cause: " + e.Message);
}
return true;
}

UnauthorizedAccessException in my own directory

I'm trying to iterate over the items on my start menu, but I keep receiving the UnauthorizedAccessException. I'm the directory's owner and my user is an administrator.
Here's my method (it's in a dll project):
// root = C:\Users\Fernando\AppData\Roaming\Microsoft\Windows\Start Menu
private void walkDirectoryTree(DirectoryInfo root) {
try {
FileInfo[] files = root.GetFiles("*.*");
foreach (FileInfo file in files) {
records.Add(new Record {Path = file.FullName});
}
DirectoryInfo[] subDirectories = root.GetDirectories();
foreach (DirectoryInfo subDirectory in subDirectories) {
walkDirectoryTree(subDirectory);
}
} catch (UnauthorizedAccessException e) {
// do some logging stuff
throw; //for debugging
}
}
The code fail when it starts to iterate over the subdirectories. What else should I do? I've already tried to create the manifest file, but it didn't work.
Another point (if is relevant): I'm just running some unit tests with visual studio (which is executed as administrator).
Based on your description, it appears there is a directory to which your user does not have access when running with UAC enabled. There is nothing inherently wrong with your code and the behavior in that situation is by design. There is nothing you can do in your code to get around the fact that your account doesn't have access to those directories in the context it is currently running.
What you'll need to do is account for the directory you don't have access to. The best way is probably by adding a few extension methods. For example
public static FileInfo[] GetFilesSafe(this DirectoryRoot root, string path) {
try {
return root.GetFiles(path);
} catch ( UnauthorizedAccessException ) {
return new FileInfo[0];
}
}

Categories