FileHelper.cs 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. #if !NETCOREAPP
  2. using System;
  3. #endif
  4. using System.IO;
  5. #if !NETCOREAPP
  6. using System.Runtime.InteropServices;
  7. #endif
  8. namespace WinSW.Util
  9. {
  10. public static class FileHelper
  11. {
  12. public static void MoveOrReplaceFile(string sourceFileName, string destFileName)
  13. {
  14. #if NETCOREAPP
  15. File.Move(sourceFileName, destFileName, true);
  16. #else
  17. string sourceFilePath = Path.GetFullPath(sourceFileName);
  18. string destFilePath = Path.GetFullPath(destFileName);
  19. if (!NativeMethods.MoveFileEx(sourceFilePath, destFilePath, NativeMethods.MOVEFILE_REPLACE_EXISTING | NativeMethods.MOVEFILE_COPY_ALLOWED))
  20. {
  21. throw GetExceptionForLastWin32Error(sourceFilePath);
  22. }
  23. #endif
  24. }
  25. #if !NETCOREAPP
  26. private static Exception GetExceptionForLastWin32Error(string path) => Marshal.GetLastWin32Error() switch
  27. {
  28. 2 => new FileNotFoundException(null, path), // ERROR_FILE_NOT_FOUND
  29. 3 => new DirectoryNotFoundException(), // ERROR_PATH_NOT_FOUND
  30. 5 => new UnauthorizedAccessException(), // ERROR_ACCESS_DENIED
  31. _ => new IOException()
  32. };
  33. private static class NativeMethods
  34. {
  35. internal const uint MOVEFILE_REPLACE_EXISTING = 0x01;
  36. internal const uint MOVEFILE_COPY_ALLOWED = 0x02;
  37. [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "MoveFileExW")]
  38. internal static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, uint dwFlags);
  39. }
  40. #endif
  41. }
  42. }