0

I have the following piece of code in a .NET 6 app that copies some files to a different destination on the file system:

DirectoryInfo targetDir = GetTargetDir();
foreach (FileInfo fi in GetFilesToCopy())
{
    fi.CopyTo(Path.Combine(targetDir.FullName, fi.Name), true);
}

As you can see, I'm passing true to the .CopyTo() method, so it overwrites the file if it already exists.
However, this seems to not work properly:

  • If the destination file does NOT exist, the copy works fine
  • If the destination file DOES exist, however, the copy operation fails and throws a UnauthorizedAccessException with an error message like 'Access to the path 'C:\my destination dir\my destination file.ext' is denied.'

I've checked the method documentation, and it says that that exception is thrown if the destination is a directory or if we're trying to copy to a different drive. However, I'm not doing any of those things (and anyway it doesn't explain why it works if the file does not exist)

I've checked all I could think of, and it all seems in order:

  • The user running the application has permission to write to that location and is the owner of the existing files
  • The files are not in use, I can easily delete them using windows explorer or cmd
  • I've also tried running the code as administrator (even though it shouldn't be needed) but same error occurs

Can anyone tell me why this is happening?

Jim G.
  • 15,141
  • 22
  • 103
  • 166
Master_T
  • 7,232
  • 11
  • 72
  • 144
  • What if you Delete the file first and then copy / move it? – Ray Jun 08 '22 at 14:16
  • 2
    Is the (existing) file read-only? Please check theese two: https://stackoverflow.com/questions/18554108/c-sharp-unauthorizedaccessexception-in-file-copy and https://stackoverflow.com/questions/8821410/why-is-access-to-the-path-denied – nilsK Jun 08 '22 at 14:17
  • @nilsK: thanks, that was it, I had to remove the ReadOnly attribute. Do you know why the CopyTo() method sets the ReadOnly attribute when copying a file? Any way to avoid it? – Master_T Jun 08 '22 at 14:43
  • If I am not wrong, you are trying to store the file to `C:` root level. To store file at `C:\` root level, you may have to run your process as `An Administrator`. I think if you try to store it under user's folder such as `c:\users\[username]\my_destination_dir\my_destination_file.ext`, then it should work. – S.Mishra Jun 08 '22 at 14:45
  • @S.Mishra: no, if you read my question you'll see I've already tried running as admin. The problem was a readonly attribute on the files. – Master_T Jun 08 '22 at 14:51
  • @Master_T glad i could help. To your question: no i have no clue. It's a feature? ;) – nilsK Jun 09 '22 at 14:49
  • @nilsK: I've done some more research, and apparently it just preserves the origin files' attributes. – Master_T Jun 09 '22 at 15:40

1 Answers1

0

Apparently the problem was the files have the Read Only attribute (thanks to @nilsK for pointing me in the right direction).

I've resolved this with the following code:

string destFile = Path.Combine(targetDir.FullName, fi.Name);
if (File.Exists(destFile))
{
    File.SetAttributes(destFile, FileAttributes.Normal);
}

fi.CopyTo(destFile, true);
Master_T
  • 7,232
  • 11
  • 72
  • 144