9

I have created a folder on the path C:\Users\MYUSER\Desktop\TEST\.

I have the following code:

private const string DIR = @"C:\Users\MYUSER\Desktop\TEST\tmp";

static void Main(string[] args)
{
    if (Directory.Exists(DIR))
        Directory.Delete(DIR);

    for (int i = 0; i < 100; i++)
    {
        var dinfo = Directory.CreateDirectory(DIR);
        Directory.Delete(DIR);
    }

    Directory.CreateDirectory(DIR);
}

When I execute the code, most times it runs OK, and I can see that there is a folder tmp inside the folder TEST.

My issue is that some other times, Directory.CreateDirectory(DIR) does not create a directory at all. I even checked the DirectoryInfo it returns and its Exists property is false and Directory.CreateDirectory(DIR) will not work because the folder does not exist. Is there any explanation for this weird behavior?

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Bsa0
  • 2,631
  • 5
  • 17
  • 23
  • On NTFS you must have permissions to do so. – Thomas Weller Aug 27 '15 at 19:17
  • 4
    Is there a real reason for this kind of code or just for test? – Sami Kuhmonen Aug 27 '15 at 19:19
  • Are you sure you're not getting an exception? Is the directory empty? – Cory Charlton Aug 27 '15 at 19:19
  • Is the directory open in another program, e.g. Windows Explorer? – Thomas Weller Aug 27 '15 at 19:21
  • 1
    I think the directory has to be empty for Directory.Delete to work. But the problem is probably that Windows hasn't finished deleting the DIR directory before the CreateDirectory line is called. So you need to wait somehow for it to finish. There are a bunch of ways to do this, but just to keep it simple, put a Thread.Sleep between Create and Delete and I bet it works every time. – Mr. B Aug 27 '15 at 19:21
  • Alternatively to `Thread.Sleep` (which only makes the odds better), you can use a `FileSystemWatcher` and subscribe to its `Deleted` event, as described here http://stackoverflow.com/questions/9370012/waiting-for-system-to-delete-file – Honza Brestan Aug 27 '15 at 19:33
  • @Mr.B I see nothing in the documentation that says `Directory.Delete` is non-blocking. – juharr Aug 27 '15 at 19:33
  • @juharr It's blocking for most of the operation, but the system can take its time to actually finish the operation. It's similar to unlocking files locked by a process that's being terminated. You can observe the process terminated, but its files still being locked. NTFS is weird like that. – Honza Brestan Aug 27 '15 at 19:35
  • The thing is sometimes it creates the folder alright, other times it doesn't. This is just a test. Yes I have the folder TEST open on explorer. I'll look into Honza Brestan's FileSystemWatcher. – Bsa0 Aug 27 '15 at 19:38
  • Are you sure it's not creating it? Just because the directory has been created doesn't necessarily mean you'll see it in the UI. Sometimes the UI gets out of sync. Refreshing (F5 on your keyboard) will update Windows Explorer. – mason Aug 27 '15 at 19:43
  • @HonzaBrestan: blocking or not, the NTFS driver should put pending operations into a queue and consider the queue when querying file system operations, shouldn't it? – Thomas Weller Aug 27 '15 at 19:47
  • @ThomasWeller To be honest I don't know the details, but I've observed this kind of behavior with .NET API many times. Even the FileSystemWatcher can misbehave, for example you get the Created event, but when you try to open the file, you cannot access it yet. I don't know why though. – Honza Brestan Aug 27 '15 at 20:01
  • @mason I'm sure it is not creating it because the call to `Directory.Delete(DIR);` says the directory does not exist. – Bsa0 Aug 27 '15 at 20:23
  • There is too much shrink-wrapped malware around to give you good odds that this can work. Only safe way is to rename the directory, then delete it, or move it to the recycle bin. – Hans Passant Aug 27 '15 at 20:56

1 Answers1

4

Had the same problem. No errors occurred, but folders simply would not be created. Just discovered the root of the issue and the easy fix.

I had something like:

Directory.CreateDirectory("/Users/MyAccount/NewFolder");
#Some code...
Directory.CreateDirectory("/Users/MyAccount/NewFolder/SubFolder");

This would fail to create folders under directories that were created before it.

Solution: Add a slash at the end of the path.

Instead of:

Directory.CreateDirectory("/Users/MyAccount/NewFolder/SubFolder");

Do:

Directory.CreateDirectory("/Users/MyAccount/NewFolder/SubFolder/");

Adding the trailing slash fixed the issue, and it now creates the folder 100% of the time. No more problems.

Asyranok
  • 950
  • 1
  • 7
  • 17
  • 2
    This is not working for me. The issue still reproduce. – m1o2 Apr 23 '18 at 20:46
  • 1
    This just seems random. Since the file system only _queues_ a directory to be deleted, trying to create it immediately after _queuing_ it for deletion may succeed, but the directory will be deleted right after the pseudo-creation. – Ray Oct 27 '18 at 16:48
  • 3
    I confirm that the behavior of Directory.CreateDirectory is totally inconsistent after a call to Directory.DeleteDirectory – Vilmir Dec 06 '18 at 13:08