mirror of
https://github.com/aphrody-labs/PowerShell.git
synced 2026-10-17 12:45:47 +00:00
Add progress to Copy-Item (#18735)
This commit is contained in:
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
|
||||
|
||||
Reference in new issue
Block a user