Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why sometimes Directory.CreateDirectory Fails?

Tags:

c#

Here is my code that I am using to extract a zip file making sure the target dir doesn't have any dirty files in it

internal void UnzipProject()
{
    if (Directory.Exists(SourceDir))
        Directory.Delete(SourceDir, true);

    if (File.Exists(CodeZipFile))
    {
        Directory.CreateDirectory(SourceDir); // fails here
        ZipFile.ExtractToDirectory(CodeZipFile, SourceDir);
    }
}

Sometime Directory.CreateDirectory(SourceDir) fails to create new dir and I get exception on next line but if I step back and retry dir creation, it works. Exactly same pattern is repeated on next execution.

EDIT
Here is the exception that actually is about dir not having been created, I can see the src dir doesn't exist:

System.UnauthorizedAccessException was unhandled
  HResult=-2147024891
  Message=Access to the path '(...MyPath...)\src\MySolution.sln' is denied.
  Source=mscorlib
  StackTrace:
       at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
       at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
       at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
       at System.IO.Compression.ZipFileExtensions.ExtractToFile(ZipArchiveEntry source, String destinationFileName, Boolean overwrite)
       at System.IO.Compression.ZipFileExtensions.ExtractToDirectory(ZipArchive source, String destinationDirectoryName)
       at System.IO.Compression.ZipFile.ExtractToDirectory(String sourceArchiveFileName, String destinationDirectoryName, Encoding entryNameEncoding)
       at System.IO.Compression.ZipFile.ExtractToDirectory(String sourceArchiveFileName, String destinationDirectoryName)
........
like image 509
WSK Avatar asked Jan 28 '16 18:01

WSK


4 Answers

Had this problem under Windows 7, .Net 4.0, VS2010. It would appear Directory.Delete() is not synchronous so the issue is timing. I'm guessing Directory.CreateDirectory() does not fail because the existing folder is marked for deletion. The new folder is then dropped as Directory.Delete() finishes.

I found this works consistently:

if (Directory.Exists(myPath))
  {
  Directory.Delete(myPath, true);
  while (Directory.Exists(myPath))
    System.Threading.Thread.Sleep(10);
  }

Directory.CreateDirectory(myPath);
like image 96
sthames42 Avatar answered Nov 16 '22 11:11

sthames42


The error is actually in the exception already.

System.UnauthorizedAccessException was unhandled

You need to add codes to check / verify that user has access to the folder.

like image 38
Batuta Avatar answered Nov 16 '22 13:11

Batuta


Thank you all for helping me resolve this issue. Problem was to create a dir just after calling its delete. In my case deleted dir was empty but probably due to file system delays, it became inaccessible before fully deleting. I am sharing the solution, for others facing same issue:

internal void UnzipProject()
{
    if (Directory.Exists(SourceDir))
    {
        DirectoryInfo di = new DirectoryInfo(SourceDir);

        foreach (FileInfo file in di.GetFiles())
            file.Delete();

        foreach (DirectoryInfo dir in di.GetDirectories())
            dir.Delete(true);
    }

    if (File.Exists(zipFile))
        ZipFile.ExtractToDirectory(zipFile, SourceDir);

    else
    {
        if (Directory.Exists(SourceDir))
            Directory.Delete(SourceDir, true);
    }
}
like image 24
WSK Avatar answered Nov 16 '22 13:11

WSK


I have experienced that behavior myself. If I am not mistaken, it happens because the Directory.Delete is still working trying to delete the directory while at the same time the Directory.CreateDirectory is trying to recreate it. The CreateDirectory will fail, because the system has that resource still locked for deletion.

I have avoided this problem by introducing a slight delay between the call to Delete and the call to CreateDirectory. Another option I remember having used was to rename the directory, then delete it. For example, if the original directory was called MyApp, I would rename it to DeleteMe and then delete that directory. CreateDirectory should be able to create the MyApp directory, since that doesn't exist anymore.

like image 1
Twilight Avatar answered Nov 16 '22 11:11

Twilight