12

I am seeing weird errors with the following code snippet:

File.Copy(oldPath, targetPath,true);
File.SetAttributes(targetPath, FileAttributes.Normal);

A file has to be moved somewhere else, and because I lack write right at the source path, I copy the file and set access rights for the destination file. On my system (Windows 7 SP1) this works fine.

However, on (as far as I know) any Windows 10 machine the program crashes at File.SetAttributes with the message

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IO.FileNotFoundException: Could not find file 'C:\ProgramData\...\BlankDb.sdf'.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.SetAttributes(String path, FileAttributes fileAttributes)

This tells me even though the code has passed the File.Copy() line, the file has not yet been copied successfully. Does File.Copy() not work synchronously anymore, or has anything else changed on differing OS in this regard?

Quite frankly, I am stumped. At first I thought of timing issues and tried wrapping the Copy call in a new Thread, until I read the File.Copy() will not return anyways before copying successfully or running into an error.

DevilSuichiro
  • 1,049
  • 8
  • 21
  • 1
    What does `File.Exists(targetPath)` after the "copy" give you? – spender Nov 12 '15 at 12:16
  • 11
    Well, very weird indeed. But you'll have to address the core problem, c:\programdata is *never* write-accessible on a properly configured machine. Many programmers have machines that are damaged by a cr*ppy installer that made the directory accessible. Written by a programmer that made the exact same mistake you made. The directory does have a clumsy name. Cold hard fact is that it is never the correct place to store a database, you **must** use appdata. – Hans Passant Nov 12 '15 at 12:18
  • Is there a virus scanner on the Windows 10 machine? – CodeCaster Nov 12 '15 at 12:44
  • @CodeCaster: Actually, I can only test this behavior on a VM, where no virus scanner is running. – DevilSuichiro Nov 12 '15 at 12:52
  • 1
    @HansPassant: this folder should be write-accessible: https://technet.microsoft.com/en-us/library/ff716245.aspx, http://stackoverflow.com/questions/16276139/difference-between-program-data-and-appdata – starteleport Nov 12 '15 at 13:25
  • @DevilSuichiro: could you try if elevating the process helps? – starteleport Nov 12 '15 at 13:30
  • @starteleport: because the application has to run without administrator access (this is the reason I'm moving the file to destination folder, where I know I have write access), this will not sort out the issue. – DevilSuichiro Nov 12 '15 at 14:44
  • @spender: the file does not exist, it not even exists after the exception is thrown. – DevilSuichiro Nov 12 '15 at 17:28
  • According to @starteleport 's link to technet. Program data doesn't work with windows store apps. Could this relate to your Windows 10 testing? – Goldfish Sandwich Nov 17 '15 at 20:35
  • @GoldfishSandwich: I don't really think this is related, shouldn't be null returned or copy fail if it does not work? – DevilSuichiro Nov 17 '15 at 21:44
  • @DevilSuichiro: I once had an issue where creating files or directories seemed not to be working either. It turned out that it had something to do with enabled encryption (as far as I remember it was TrueCrypt) in the virtual machine. I never was able to figure out what the problem was exactly but maybe it is something simillar in your case. But you haven't activated the encryption on the partition, right? – Markus Safar Nov 23 '15 at 21:31

3 Answers3

0

You can try this code. (Pls change the paths to yours)

 static void Main(string[] args)
    {
        var oldDir = new DirectoryInfo("D:\\Personal\\Projects\\Desktop\\StackSolutions\\ConsoleApp1\\ConsoleApp1\\OldFilePath\\funy.jpg");
        var newDir = new DirectoryInfo("D:\\Personal\\Projects\\Desktop\\StackSolutions\\ConsoleApp1\\ConsoleApp1\\NewFilePath\\funy1.jpg");

        var oldPath = oldDir.FullName;
        var targetPath = newDir.FullName;

        File.Copy(oldPath, targetPath);
        File.SetAttributes(targetPath, FileAttributes.Normal);
    }
0

You can just bypass File.Copy() entirely by just writing the copied file to the destination yourself.

FileStream src = new FileStream(<!!!INSERT SOURCE NAME HERE!!!>, FileMode.Open, FileAccess.Read);
FileStream dst = new FileStream(<!!!INSERT DESTINATION NAME HERE!!!>, FileMode.CreateNew, FileAccess.Write);
byte[] buf = new byte[2097152];
while(src.Position != src.Length)
{
  int numRead = src.Read(buf, 0, buf.Length);
  dst.Write(buf, 0, numRead);
}
dst.Flush();
dst.Close();
dst = null;
src.Close();
src = null;

Make sure to replace the placeholders with the strings referencing the source and destination files. This will simply copy the source file, 2MB at a time, until all the data is copied.

  • welcome LaserLinux and nice to start with an answer right away, but have you tested the File.SetAttributes(targetPath, FileAttributes.Normal); ? The question is not about the copy itself, it is about the latency of the remote file being available *after* the copy on certain OS'es, specifically Windows10. It would enhance your answer, if the test turns out to work. – Goodies Jun 21 '20 at 22:37
-1

You can try sharing the directory 'C:\ProgramData...' and it'll solve the problem, if it's because of permission issue on Windows 10.

You can refer, http://www.geeksquad.co.uk/articles/how-to-set-up-file-sharing-on-windows-10 to get help to share your folder.

user836846
  • 74
  • 2