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
+ }
+}