Add progress to Copy-Item (#18735)

This commit is contained in:
Steve Lee authored and GitHub committed 2023-01-25 16:34:44 +05:00
1 parent 44f2792a36
commit 1c27a0ceac
4 files changed
+93 -2

No files matched your search

@@ -6,6 +6,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
@@ -18,6 +19,7 @@ using System.Runtime.InteropServices;
using System.Security;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.XPath;
@@ -58,6 +60,8 @@ namespace Microsoft.PowerShell.Commands
// copy script will accommodate the new value.
private const int FILETRANSFERSIZE = 4 * 1024 * 1024;
private const int COPY_FILE_ACTIVITY_ID = 0;
// The name of the key in an exception's Data dictionary when attempting
// to copy an item onto itself.
private const string SelfCopyDataKey = "SelfCopy";
@@ -3548,7 +3552,25 @@ namespace Microsoft.PowerShell.Commands
}
else // Copy-Item local
{
if (Context != null && Context.ExecutionContext.SessionState.PSVariable.Get(SpecialVariables.ProgressPreferenceVarPath.UserPath).Value is ActionPreference progressPreference && progressPreference == ActionPreference.Continue)
{
{
Task.Run(() =>
{
GetTotalFiles(path, recurse);
});
_copyStopwatch.Start();
}
}
CopyItemLocalOrToSession(path, destinationPath, recurse, Force, null);
if (_totalFiles > 0)
{
_copyStopwatch.Stop();
var progress = new ProgressRecord(COPY_FILE_ACTIVITY_ID, " ", " ");
progress.RecordType = ProgressRecordType.Completed;
WriteProgress(progress);
}
}
}
@@ -3556,6 +3578,47 @@ namespace Microsoft.PowerShell.Commands
_excludeMatcher = null;
}
private void GetTotalFiles(string path, bool recurse)
{
bool isContainer = IsItemContainer(path);
try
{
if (isContainer)
{
var enumOptions = new EnumerationOptions()
{
IgnoreInaccessible = true,
AttributesToSkip = 0,
RecurseSubdirectories = recurse
};
var directory = new DirectoryInfo(path);
foreach (var file in directory.EnumerateFiles("*", enumOptions))
{
if (!SessionStateUtilities.MatchesAnyWildcardPattern(file.Name, _excludeMatcher, defaultValue: false))
{
_totalFiles++;
_totalBytes += file.Length;
}
}
}
else
{
var file = new FileInfo(path);
if (!SessionStateUtilities.MatchesAnyWildcardPattern(file.Name, _excludeMatcher, defaultValue: false))
{
_totalFiles++;
_totalBytes += file.Length;
}
}
}
catch
{
// ignore exception
}
}
private void CopyItemFromRemoteSession(string path, string destinationPath, bool recurse, bool force, PSSession fromSession)
{
using (System.Management.Automation.PowerShell ps = System.Management.Automation.PowerShell.Create())
@@ -3864,6 +3927,22 @@ namespace Microsoft.PowerShell.Commands
FileInfo result = new FileInfo(destinationPath);
WriteItemObject(result, destinationPath, false);
if (_totalFiles > 0)
{
_copiedFiles++;
_copiedBytes += file.Length;
double speed = (double)(_copiedBytes / 1024 / 1024) / _copyStopwatch.Elapsed.TotalSeconds;
var progress = new ProgressRecord(
COPY_FILE_ACTIVITY_ID,
StringUtil.Format(FileSystemProviderStrings.CopyingLocalFileActivity, _copiedFiles, _totalFiles),
StringUtil.Format(FileSystemProviderStrings.CopyingLocalBytesStatus, Utils.DisplayHumanReadableFileSize(_copiedBytes), Utils.DisplayHumanReadableFileSize(_totalBytes), speed)
);
var percentComplete = (int)Math.Min(_copiedBytes * 100 / _totalBytes, 100);
progress.PercentComplete = percentComplete;
progress.RecordType = ProgressRecordType.Processing;
WriteProgress(progress);
}
}
else
{
@@ -4788,6 +4867,12 @@ namespace Microsoft.PowerShell.Commands
return pathIsReservedDeviceName;
}
private long _totalFiles;
private long _totalBytes;
private long _copiedFiles;
private long _copiedBytes;
private readonly Stopwatch _copyStopwatch = new Stopwatch();
#endregion CopyItem
#endregion ContainerCmdletProvider members