diff --git a/src/Core/ServiceWrapper/Main.cs b/src/Core/ServiceWrapper/Main.cs index 98025b7..a47f3f4 100644 --- a/src/Core/ServiceWrapper/Main.cs +++ b/src/Core/ServiceWrapper/Main.cs @@ -106,7 +106,7 @@ namespace winsw continue; } - CopyFile(tokens[0], tokens[1]); + MoveFile(tokens[0], tokens[1]); } } finally @@ -118,16 +118,15 @@ namespace winsw /// /// File replacement. /// - private void CopyFile(string sourceFileName, string destFileName) + private void MoveFile(string sourceFileName, string destFileName) { try { - File.Delete(destFileName); - File.Move(sourceFileName, destFileName); + FileHelper.MoveOrReplaceFile(sourceFileName, destFileName); } catch (IOException e) { - LogEvent("Failed to copy :" + sourceFileName + " to " + destFileName + " because " + e.Message); + LogEvent("Failed to move :" + sourceFileName + " to " + destFileName + " because " + e.Message); } } diff --git a/src/Core/WinSWCore/Download.cs b/src/Core/WinSWCore/Download.cs index 1891617..69b8dae 100755 --- a/src/Core/WinSWCore/Download.cs +++ b/src/Core/WinSWCore/Download.cs @@ -181,14 +181,7 @@ namespace winsw #endif } -#if NETCOREAPP - File.Move(tmpFilePath, To, true); -#else - if (File.Exists(To)) - File.Delete(To); - - File.Move(tmpFilePath, To); -#endif + FileHelper.MoveOrReplaceFile(To + ".tmp", To); } #if NET20 diff --git a/src/Core/WinSWCore/LogAppenders.cs b/src/Core/WinSWCore/LogAppenders.cs index 31d5c78..0844c8e 100644 --- a/src/Core/WinSWCore/LogAppenders.cs +++ b/src/Core/WinSWCore/LogAppenders.cs @@ -8,6 +8,7 @@ using System.Threading; #if !VNEXT using ICSharpCode.SharpZipLib.Zip; #endif +using winsw.Util; namespace winsw { @@ -52,16 +53,15 @@ namespace winsw /// /// File replacement. /// - protected void CopyFile(string sourceFileName, string destFileName) + protected void MoveFile(string sourceFileName, string destFileName) { try { - File.Delete(destFileName); - File.Move(sourceFileName, destFileName); + FileHelper.MoveOrReplaceFile(sourceFileName, destFileName); } catch (IOException e) { - EventLogger.LogEvent("Failed to copy :" + sourceFileName + " to " + destFileName + " because " + e.Message); + EventLogger.LogEvent("Failed to move :" + sourceFileName + " to " + destFileName + " because " + e.Message); } } } @@ -286,10 +286,10 @@ namespace winsw public override void log(StreamReader outputReader, StreamReader errorReader) { if (!OutFileDisabled) - CopyFile(OutputLogFileName, OutputLogFileName + ".old"); + MoveFile(OutputLogFileName, OutputLogFileName + ".old"); if (!ErrFileDisabled) - CopyFile(ErrorLogFileName, ErrorLogFileName + ".old"); + MoveFile(ErrorLogFileName, ErrorLogFileName + ".old"); base.log(outputReader, errorReader); } diff --git a/src/Core/WinSWCore/Util/FileHelper.cs b/src/Core/WinSWCore/Util/FileHelper.cs new file mode 100644 index 0000000..557f86c --- /dev/null +++ b/src/Core/WinSWCore/Util/FileHelper.cs @@ -0,0 +1,39 @@ +#if !NETCOREAPP +using System.ComponentModel; +#endif +using System.IO; +#if !NETCOREAPP +using System.Runtime.InteropServices; +#endif + +namespace winsw.Util +{ + public static class FileHelper + { + public static void MoveOrReplaceFile(string sourceFileName, string destFileName) + { +#if NETCOREAPP + File.Move(sourceFileName, destFileName, true); +#else + string sourceFilePath = Path.GetFullPath(sourceFileName); + string destFilePath = Path.GetFullPath(destFileName); + + if (!NativeMethods.MoveFileEx(sourceFilePath, destFilePath, NativeMethods.MOVEFILE_REPLACE_EXISTING | NativeMethods.MOVEFILE_COPY_ALLOWED)) + { + throw new Win32Exception(); + } +#endif + } +#if !NETCOREAPP + + private static class NativeMethods + { + internal const uint MOVEFILE_REPLACE_EXISTING = 0x01; + internal const uint MOVEFILE_COPY_ALLOWED = 0x02; + + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "MoveFileExW")] + internal static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, uint dwFlags); + } +#endif + } +}