Access To The Path ... Is Denied

16.3k Views Asked by At

Alright, I've seen tons of questions about this thing, but still, no one answers my question. In fact, each one of the questions I saw differs from the other, this access thing really seems to be hassling programmers.

Please check out the code:

DirectoryInfo Dir1 = Directory.CreateDirectory(Desktop + "\\DIR1");
DirectoryInfo Dir2 = Directory.CreateDirectory(Desktop + "\\DIR2");
//* Lets Create a couple of SubDirs in DIR1
for (int i = 0; i < 5; i++)
{
  // this will create 5 SubDirs in DIR1, named Sub1, Sub2 ... Sub5.
  Dir1.CreateSubdirectory("Sub" + (i + 1).ToString()); 
  //* lets create 5 text files in each SubDir:
  for (int j = 0; j < 5; j++)
  {
    File.Create(Dir1.FullName + "\\Sub"+(i+1).ToString() + "\\text"+(j+1).ToString() + ".txt"); 
  }
}

//* Lets Move all what we created in DIR1 to DIR2 (THIS IS WHERE I'M GETTING THE EXCEPTION
Directory.Move(Dir1.FullName, Dir2.FullName + "\\DIR1");
// I also Tried Dir1.MoveTo(Dir2.FullName + "\\DIR1");

Stack Trace:

at System.IO.DirectoryInfo.MoveTo(String destDirName)
at Directory_Class.Program.Main(String[] args) in c:\users\vexe\documents\visual studio 2010\Projects\Directory_Class\Directory_Class\Program.cs:line 207
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

And of course, I tried the usual:

DirectorySecurity DirSec = Dir1.GetAccessControl();
string user = Environment.UserName;
DirSec.ResetAccessRule(new FileSystemAccessRule(user, FileSystemRights.FullControl, AccessControlType.Allow));
Dir1.SetAccessControl(DirSec);

But it didn't change a bit!

I also tried changing the permissions manually, by right clicking dir1 -> properties -> security -> edit -> add -> typed everyone (in the enter object names to select) -> ok -> fullcontrol to everyone. (I also saw that my user account had full control as well)

Any hints would be deeply appreciated

4

There are 4 best solutions below

2
On BEST ANSWER

While it is an Access Denied exception, it sounds like the text files are in use and cannot be moved because there are open references to the file.

The File.Create method returns a FileStream object which I'd imagine must be closed/disposed before the files can be modified.

Try the following for your inner loop:

  for (int j = 0; j < 5; j++)
  {
    using(var fs = File.Create(Dir1.FullName + "\\Sub"+(i+1).ToString() + "\\text"+(j+1).ToString() + ".txt"))
    {
        //fs.WriteByte(...);
        fs.Close();
    }
  }
1
On

First off, you should use Path.Combine instead of doing string concatenation.
Second off, the stack trace isn't as helpful as the exception being thrown.

I imagine your problem might be fixed by doing this though:

Directory.Move(Dir1.FullName, Dir2.FullName);

If that fixes it, then the issue is with the DIR1 subdirectory you're trying to move it to.

0
On

As a debugging, step you should set failure auditing on the two folders (under advanced security settings). Just set everyone to audit all failures, then try your operation again. Depending on the OS version that you are running you should get the user account being used for the operation and what privilege was missing. Also make sure that there are no deny permissions set on the folder as they override all other permissions. You will want to look at the security event log. If there are no failure audits for the operation then it is not a permissions issues.

0
On

It seems to me Windows loves blocking deletes (renames) of directories for literally no reason. I'm sure it has one, but I don't care what it is. I've found that deleting the contents of the directory, then deleting the empty folder works every time. It works with the following rename as well.

I came up with this, as windows was giving me access to path denied for the FROM directory. I was just renaming it within the app, not really moving locations. Anyway, based on the above information, I came up with this and it works.

public static void MoveTo_BruteItAsNecessary(this DirectoryInfo FROM, string TO, bool recycle = false)
{
    try
    {
        FROM.MoveTo(TO);
    }
    catch (IOException ex)
    {
        if (ex.Contains($"Access to the path '{FROM.FullName}' is denied."))
        {   // Contains checks the Message & InnerException.Message(s) recursively
            System.IO.Directory.CreateDirectory(TO);
            foreach (var dir in FROM.GetDirectories())
                dir.MoveTo(Path.Combine(TO, dir.Name));
            foreach (var file in FROM.GetFiles())
                file.MoveTo(Path.Combine(TO, file.Name));
            if (recycle)
                FROM.Recycle();
            else
                FROM.Delete();
        }
        else
            throw;
    }
}