diff --git a/AlphaFS.UnitTest/AlphaFS.UnitTest.csproj b/AlphaFS.UnitTest/AlphaFS.UnitTest.csproj
index 81e8b72b8..8792846dd 100644
--- a/AlphaFS.UnitTest/AlphaFS.UnitTest.csproj
+++ b/AlphaFS.UnitTest/AlphaFS.UnitTest.csproj
@@ -223,6 +223,7 @@
+
diff --git a/AlphaFS.UnitTest/Directory Class/Directory.Move/Directory.Move_UsingFiles.cs b/AlphaFS.UnitTest/Directory Class/Directory.Move/Directory.Move_UsingFiles.cs
new file mode 100644
index 000000000..929d9b951
--- /dev/null
+++ b/AlphaFS.UnitTest/Directory Class/Directory.Move/Directory.Move_UsingFiles.cs
@@ -0,0 +1,112 @@
+/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Reflection;
+
+namespace AlphaFS.UnitTest
+{
+ public partial class Directory_MoveTest
+ {
+ // Pattern: ___
+
+
+ [TestMethod]
+ public void Directory_Move_UsingFiles_LocalAndNetwork_Success()
+ {
+ Directory_Move_UsingFiles(false);
+ Directory_Move_UsingFiles(true);
+ }
+
+
+ private void Directory_Move_UsingFiles(bool isNetwork)
+ {
+ UnitTestConstants.PrintUnitTestHeader(isNetwork);
+ Console.WriteLine();
+
+
+ // Change the drive letter to suit your environment.
+ var destinationDriveLetter = "D";
+ var destinationDrivePath = destinationDriveLetter + Alphaleonis.Win32.Filesystem.Path.VolumeSeparator +Alphaleonis.Win32.Filesystem.Path.DirectorySeparator;
+
+
+ if (!Alphaleonis.Win32.Filesystem.Directory.ExistsDrive(destinationDrivePath, false))
+ Assert.Inconclusive("This unit tests needs an additional drive: [" + destinationDrivePath + "]");
+
+
+
+
+ var tempPath = UnitTestConstants.TempFolder;
+ if (isNetwork)
+ tempPath = Alphaleonis.Win32.Filesystem.Path.LocalToUnc(tempPath);
+
+
+ using (var rootDir = new TemporaryDirectory(tempPath, MethodBase.GetCurrentMethod().Name))
+ {
+ const string srcFileName = "Src file.log";
+ const string dstFileName = "Dst file.log";
+
+ var srcFile = System.IO.Path.Combine(rootDir.Directory.FullName, srcFileName);
+
+ var dstFile = System.IO.Path.Combine(destinationDrivePath, dstFileName);
+ if (isNetwork)
+ dstFile = Alphaleonis.Win32.Filesystem.Path.LocalToUnc(dstFile);
+
+
+ System.IO.File.AppendAllText(srcFile, new string('*', new Random().Next(1, 1024)));
+
+ const Alphaleonis.Win32.Filesystem.MoveOptions options = Alphaleonis.Win32.Filesystem.MoveOptions.CopyAllowed | Alphaleonis.Win32.Filesystem.MoveOptions.WriteThrough | Alphaleonis.Win32.Filesystem.MoveOptions.ReplaceExisting;
+
+ Console.WriteLine("Src File Path: [{0}]", srcFile);
+ Console.WriteLine("Dst File Path: [{0}]", dstFile);
+
+
+
+
+ var cmr = Alphaleonis.Win32.Filesystem.Directory.Move(srcFile, dstFile, options);
+
+ UnitTestConstants.Dump(cmr, -18);
+
+
+ Assert.IsFalse(System.IO.Directory.Exists(dstFile));
+
+ Assert.IsTrue(System.IO.File.Exists(dstFile));
+
+ Assert.AreEqual(new System.IO.FileInfo(srcFile).Length, new System.IO.FileInfo(dstFile).Length);
+
+
+ Assert.IsTrue(cmr.IsCopy);
+ Assert.IsTrue(cmr.IsEmulatedMove);
+
+ Assert.IsTrue(cmr.IsFile);
+ Assert.IsFalse(cmr.IsDirectory);
+
+ Assert.IsFalse(cmr.IsCanceled);
+ Assert.AreEqual(0, cmr.TotalFolders);
+ Assert.AreEqual(1, cmr.TotalFiles);
+ }
+
+
+ Console.WriteLine();
+ }
+ }
+}
diff --git a/AlphaFS/Filesystem/CopyMoveResult.cs b/AlphaFS/Filesystem/CopyMoveResult.cs
index 6a2e6a0d2..3ee30dff0 100644
--- a/AlphaFS/Filesystem/CopyMoveResult.cs
+++ b/AlphaFS/Filesystem/CopyMoveResult.cs
@@ -61,15 +61,15 @@ private CopyMoveResult(string source, string destination)
/// Indicates the full path to the source file or directory.
/// Indicates the full path to the destination file or directory.
/// >When the action is a Copy, Move otherwise.
- /// When indicates the sources is a directory; file otherwise.
+ /// When indicates the sources is a directory; file otherwise.
/// if original Timestamps must be preserved, otherwise. This parameter is ignored for move operations.
/// When indicates the Move action used a fallback of Copy + Delete actions.
- public CopyMoveResult(string source, string destination, bool isCopy, bool isDirectory, bool preserveDates, bool emulatedMove) : this(source, destination)
+ public CopyMoveResult(string source, string destination, bool isCopy, bool isFolder, bool preserveDates, bool emulatedMove) : this(source, destination)
{
IsEmulatedMove = emulatedMove;
IsCopy = isCopy;
- IsDirectory = isDirectory;
+ IsDirectory = isFolder;
TimestampsCopied = preserveDates;
}
diff --git a/AlphaFS/Filesystem/Directory Class/Directory.Copy.cs b/AlphaFS/Filesystem/Directory Class/Directory.Copy.cs
index 9686d2cd2..937c95366 100644
--- a/AlphaFS/Filesystem/Directory Class/Directory.Copy.cs
+++ b/AlphaFS/Filesystem/Directory Class/Directory.Copy.cs
@@ -696,7 +696,7 @@ internal static CopyMoveResult CopyMoveCore(KernelTransaction transaction, strin
string sourcePathLp;
string destinationPathLp;
bool isCopy;
-
+
// A Move action fallback using Copy + Delete.
bool emulateMove;
@@ -706,25 +706,29 @@ internal static CopyMoveResult CopyMoveCore(KernelTransaction transaction, strin
File.ValidateAndUpdatePathsAndOptions(transaction, sourcePath, destinationPath, copyOptions, moveOptions, pathFormat, out sourcePathLp, out destinationPathLp, out isCopy, out emulateMove, out delayUntilReboot, out deleteOnStartup);
-
+
+
+ // Directory.Move is applicable to both folders and files.
+ var isFile = File.ExistsCore(transaction, false, sourcePath, PathFormat.LongFullPath);
+
// Check for local or network drives, such as: "C:" or "\\server\c$".
- ExistsDriveOrFolderOrFile(transaction, sourcePathLp, true, (int) Win32Errors.NO_ERROR, true, false);
+ ExistsDriveOrFolderOrFile(transaction, sourcePathLp, !isFile, (int) Win32Errors.NO_ERROR, true, false);
// File Move action: destinationPath is allowed to be null when MoveOptions.DelayUntilReboot is specified.
if (!delayUntilReboot)
- ExistsDriveOrFolderOrFile(transaction, destinationPathLp, true, (int) Win32Errors.NO_ERROR, true, false);
+ ExistsDriveOrFolderOrFile(transaction, destinationPathLp, !isFile, (int) Win32Errors.NO_ERROR, true, false);
// Process Move action options, possible fallback to Copy action.
if (!isCopy && !deleteOnStartup)
ValidateAndUpdateCopyMoveAction(sourcePathLp, destinationPathLp, copyOptions, moveOptions, out copyOptions, out moveOptions, out isCopy, out emulateMove);
-
-
+
+
pathFormat = PathFormat.LongFullPath;
-
- var cmr = copyMoveResult ?? new CopyMoveResult(sourcePath, destinationPath, isCopy, true, preserveDates, emulateMove);
+
+ var cmr = copyMoveResult ?? new CopyMoveResult(sourcePath, destinationPath, isCopy, !isFile, preserveDates, emulateMove);
if (isCopy)
@@ -745,7 +749,11 @@ internal static CopyMoveResult CopyMoveCore(KernelTransaction transaction, strin
}
else
- cmr = CopyDeleteCore(transaction, sourcePathLp, destinationPathLp, preserveDates, emulateMove, copyOptions, progressHandler, userProgressData, cmr);
+ {
+ cmr = isFile
+ ? File.CopyMoveCore(transaction, true, false, sourcePathLp, destinationPathLp, copyOptions, null, preserveDates, progressHandler, userProgressData, cmr, PathFormat.LongFullPath)
+ : CopyDeleteDirectoryCore(transaction, sourcePathLp, destinationPathLp, preserveDates, emulateMove, copyOptions, progressHandler, userProgressData, cmr);
+ }
}
// Move
@@ -754,7 +762,7 @@ internal static CopyMoveResult CopyMoveCore(KernelTransaction transaction, strin
// AlphaFS feature to overcome a MoveFileXxx limitation.
// MoveOptions.ReplaceExisting: This value cannot be used if lpNewFileName or lpExistingFileName names a directory.
- if (!delayUntilReboot && File.CanOverwrite(moveOptions))
+ if (!isFile && !delayUntilReboot && File.CanOverwrite(moveOptions))
DeleteDirectoryCore(transaction, null, destinationPathLp, true, true, true, pathFormat);
// 2017-06-07: A large target directory will probably create a progress-less delay in UI.
@@ -764,7 +772,7 @@ internal static CopyMoveResult CopyMoveCore(KernelTransaction transaction, strin
// Moves a file or directory, including its children.
// Copies an existing directory, including its children to a new directory.
- cmr = File.CopyMoveCore(transaction, true, true, sourcePathLp, destinationPathLp, copyOptions, moveOptions, preserveDates, progressHandler, userProgressData, cmr, pathFormat);
+ cmr = File.CopyMoveCore(transaction, true, !isFile, sourcePathLp, destinationPathLp, copyOptions, moveOptions, preserveDates, progressHandler, userProgressData, cmr, pathFormat);
// If the move happened on the same drive, we have no knowledge of the number of files/folders.
@@ -780,7 +788,7 @@ internal static CopyMoveResult CopyMoveCore(KernelTransaction transaction, strin
}
- private static CopyMoveResult CopyDeleteCore(KernelTransaction transaction, string sourcePathLp, string destinationPathLp, bool preserveDates, bool emulateMove, CopyOptions? copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, CopyMoveResult copyMoveResult)
+ private static CopyMoveResult CopyDeleteDirectoryCore(KernelTransaction transaction, string sourcePathLp, string destinationPathLp, bool preserveDates, bool emulateMove, CopyOptions? copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, CopyMoveResult copyMoveResult)
{
var cmr = copyMoveResult ?? new CopyMoveResult(sourcePathLp, destinationPathLp, true, true, preserveDates, emulateMove);
@@ -870,7 +878,7 @@ private static CopyMoveResult CopyDeleteCore(KernelTransaction transaction, stri
return cmr;
}
-
+
private static void ValidateAndUpdateCopyMoveAction(string sourcePathLp, string destinationPathLp, CopyOptions? copyOptions, MoveOptions? moveOptions, out CopyOptions? newCopyOptions, out MoveOptions? newMoveOptions, out bool isCopy, out bool emulateMove)
{
diff --git a/AlphaFS/Filesystem/File Class/File.Copy.cs b/AlphaFS/Filesystem/File Class/File.Copy.cs
index 4d8334817..adac33785 100644
--- a/AlphaFS/Filesystem/File Class/File.Copy.cs
+++ b/AlphaFS/Filesystem/File Class/File.Copy.cs
@@ -800,7 +800,7 @@ internal static CopyMoveResult CopyMoveCore(KernelTransaction transaction, bool
var cmr = copyMoveResult ?? new CopyMoveResult(sourcePath, destinationPath, isCopy, isFolder, preserveDates, emulateMove);
var isMove = !isCopy;
- var isSingleFileAction = null == copyMoveResult && !isFolder;
+ var isSingleFileAction = null == copyMoveResult && !isFolder || cmr.IsFile;
preserveDates = preserveDates && isCopy && !isFolder;
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5e4ed5474..0786994be 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,9 +6,9 @@ Version 2.2.2 (2018-XX-XX)
### Bugs Fixed
-- Issue #436: Directory.GetFiles() with relative path (Thx stellarbear)
-- Issue #437: Fixed PathTooLongException for boundary case of directory name length in Path.NormalizePath (Thx okrushelnitsky)
-
+- Issue #434: `Directory.Move` operation worked in v2.0.1, but now fails in v.2.2.1
+- Issue #436: `Directory.GetFiles()` with relative path (Thx stellarbear)
+- Issue #437: Fixed `PathTooLongException` for boundary case of directory name length in `Path.NormalizePath` (Thx okrushelnitsky)
Version 2.2.1 (2018-04-05)
-------------