I found a very weird bug when using FileInfo.Delete()
or Directory.Delete(path, true)
after copying a folder.
Problem:
- Copy a folder containing many files and a few subfolders recursively
- Try to delete the original folder recursively
- Exactly on the third file inside the folder, the application will crash without throwing an
Exception
- It's not always the same file, as the first two get deleted normally, the third fails. (If I try again, the first will be the one that failed last, and will be succesfully deleted)
Reproduction:
In a WPF
application, a button with the following methods cause the crash (later I'll try to reproduce in a Console Application):
private void Tester_Click(object sender, RoutedEventArgs e)
{
string copyFolderToThisPath = @"C:\Users\xxx\Desktop\xxxx\xxxx_xxx - Copia";
string copyAndDeleteThisFolder = @"C:\Users\xxx\Desktop\xxxx\Prov\Nova pasta (3)";
//copy the directory recursively: works
CopyOrDeleteDirectory(new DirectoryInfo(copyAndDeleteThisFolder), copyFolderToThisPath);
//delete the directory recursively: fails at the third file of the main folder - always
CopyOrDeleteDirectory(new DirectoryInfo(copyAndDeleteThisFolder), null);
}
Recursive copy or delete:
(I know that Directory.Delete(path, true)
exists, but it also fails, I created recursive deletion to check what was going on)
/// <summary>
/// Copies or deletes a directory recursively - Use copyToPath == null to delete
/// </summary>
/// <param name="copyToPath">Destination to copy. If null, will delete the directory</param>
/// <returns>true if all operations with this directory were successful</returns>
private bool CopyOrDeleteDirectory(DirectoryInfo directory, string copyToPath)
{
bool isCopy = !string.IsNullOrEmpty(copyToPath); //defines if the method will copy or delete
FileInfo[] files = null;
DirectoryInfo[] dirs = null;
//try get files and subdirectories
try
{
files = directory.GetFiles();
dirs = directory.GetDirectories();
if (isCopy)
Directory.CreateDirectory(copyToPath);
}
catch (Exception e)
{
MessageBox.Show("Could not enumerate folder " + directory.Name);
return false;
}
bool success = true;
//copy or delete files
foreach (FileInfo file in files)
{
try
{
if (isCopy)
file.CopyTo(System.IO.Path.Combine(copyToPath, file.Name));
else
file.Delete(); //exactly at the third iteration it will crash the application
}
catch (Exception e) //the exception will NEVER be thrown!! Catch block is not reached
{
MessageBox.Show("Failed to operate file " + file.Name);
success = false;
}
}
//copy or delete subdirectories
foreach (DirectoryInfo d in dirs)
{
try
{
string subPath = isCopy ? System.IO.Path.Combine(copyToPath, d.Name) : null;
bool subDirSuccess = CopyOrDeleteDirectory(d, subPath);
if (!subDirSuccess)
success = false;
}
catch (StackOverflowException ex)
{
MessageBox.Show("StackOverflow in recursive function");
success = false;
}
}
if (success && (!isCopy))
{
try
{
directory.Delete();
}
catch (Exception e)
{
MessageBox.Show("Failed to delete directory " + directory.Name);
success = false;
}
}
return success;
}
Important details:
- This is a "bug reproduction" code. The original application is bigger, and there is interaction with the user between the copy and the deletion. This "copy and delete" is not the normal flow of the application, but the user may do this by calling two different commands of the application
- There is a time interval with the application fully responsive between the user clicking copy and clicking delete. The copy operation is completed before the user can do anything else.
- The problem does not happen if only the delete command is called, it will happen if there is a copy first
- I tried freeing the resources, but it doesn't seem that it's possible for
FileInfo
andDirectoryInfo
. Anyway I tried setting everything to null everywhere as soon as possible, no success. - No
Exception
is thrown, the application fully crashes - All files are accessible, none of them are read only
- Windows 10
- WPF application with C#
- Visual Studio 2017 debugging (The problem happens either stepping or not)