我正在尝试在powershell中创建一个自定义Robocopy状态GUI,这是我的基本代码。
$script:Robocopy = Start-Process -FilePath robocopy.exe -ArgumentList $ArgumentList -Verbose -PassThru -NoNewWindow;
$RCStatus = Start-Job -Name RCLOOP -ArgumentList $Robocopy, $ReportGap, $RobocopyLogPath, $RegexBytes, $RobocopyFileProgress, $RobocopyMBProgress, $RobocopyGBProgress, $RobocopyPcntProgress, $RobocopySpeed {
param ($Robocopy, $ReportGap, $RobocopyLogPath, $RegexBytes, $RobocopyFileProgress, $RobocopyMBProgress, $RobocopyGBProgress, $RobocopyPcntProgress, $RobocopySpeed)
$iterations = 0
[array]$avgSpeedarray = @()
while (!$Robocopy.HasExited) {
Start-Sleep -Milliseconds $ReportGap;
$BytesCopied = 0;
$LogContent = Get-Content -Path $RobocopyLogPath;
$BytesCopied = [Regex]::Matches($LogContent, $RegexBytes) | ForEach-Object -Process { $BytesCopied += $_.Value; } -End { $BytesCopied; };
$global:MBCopied = ($BytesCopied / 1048576)
$global:GBCopied = ($BytesCopied / 1073741824)
$script:CopiedFileCount = $LogContent.Count - 1;
$iterations++
if ($iterations % 2 -eq 1) {
$M = $MBCopied
}
else {
$B = $MBCopied
$script:TSpeed = ($B - $M) * 8
$avgSpeedarray += $script:TSpeed
if ($avgSpeedarray.count -gt 4) {
$script:avgSpeed = (($avgSpeedarray[-1..-10] | Measure-Object -sum).sum) / 10
if ($avgSpeedarray.count -gt 19) {
$keep = $avgSpeedarray[-1..-9]
$avgSpeedarray = @()
$avgSpeedarray += $keep
}
}
}
if ($iterations % 20 -eq 0) {
$keepAwake
}
Write-Verbose -Message ('MB copied: {0}' -f $MBCopied);
Write-Verbose -Message ('Files copied: {0}' -f $LogContent.Count);
$Percentage = 0;
if ($BytesCopied -gt 0) {
$Percentage = (($BytesCopied / $BytesTotal) * 100)
}
#Write-Progress -Activity Robocopy -Status ("Copied {0} of {1} | {2}GB of {3}GB | {4}MB of {5}MB | {6}% Complete (Average: {7}Mbps)" -f $CopiedFileCount, $TotalFileCount, [Math]::Round($GBCopied, 2), [Math]::Round($GBTotal, 2), [Math]::Round($MBCopied, 2), [Math]::Round($MBTotal), [Math]::Round($Percentage, 2), [Math]::Round($script:avgSpeed,2)) -PercentComplete $Percentage
$RobocopyFileProgress.Text = ("Files: {0} of {1}" -f $CopiedFileCount, $TotalFileCount)
$RobocopyMBProgress.Text = ("Data: {0}MB of {1}MB" -f [Math]::Round($MBCopied, 2), [Math]::Round($MBTotal, 2))
$RobocopyGBProgress.Text = ("Data: {0}GB of {1}GB" -f [Math]::Round($GBCopied, 2), [Math]::Round($GBTotal, 2))
$RobocopyPcntProgress.Text = ("Percentage: {0}%" -f [Math]::Round($Percentage, 2))
$RobocopySpeed.text = ("Speed: {0}Mbps" -f [Math]::Round($script:avgSpeed, 2))
}
}
$RobocopyProgressGUI.Show()
#endregion Progress loop
Register-ObjectEvent -InputObject $script:Robocopy -EventName OutputDataReceived -SourceIdentifier 'RobocopyStatus' -Action {
$RobocopyFileProgress.Text = ("Files: {0} of {1}" -f $CopiedFileCount, $TotalFileCount)
$RobocopyMBProgress.Text = ("Data: {0}MB of {1}MB" -f [Math]::Round($MBCopied, 2), [Math]::Round($MBTotal, 2))
$RobocopyGBProgress.Text = ("Data: {0}GB of {1}GB" -f [Math]::Round($GBCopied, 2), [Math]::Round($GBTotal, 2))
$RobocopyPcntProgress.Text = ("Percentage: {0}%" -f [Math]::Round($Percentage, 2))
$RobocopySpeed.text = ("Speed: {0}Mbps" -f [Math]::Round($script:avgSpeed, 2))
}
我的一个问题是,我的表单只是打开和关闭没有任何脚本告诉它关闭,另一个是上面输出的所有代码是关于作业的信息,而不是作业输出的内容。
我知道我的代码非常冗长,这是故障排除过程的一部分,我知道c#是一个更好的选择,但我试图在powershell中实现它,因为我不太擅长c#。任何帮助或建议将是惊人的。如果您需要我的程序中我遗漏的任何其他代码,请让我知道,我会提供它
下面是如何在powershell中使用带有进度条的robocopy的示例。我改编了一个现有的答案,然后根据我在使用它时发现的一些问题进一步完善它。希望能有所帮助。
进步在大文件副本(Copy-Item,Write-Progress ?)
如果你想做一个GUI,我也建议使用WPF/xaml而不是winforms。Winforms似乎在PowerShell有点不稳定。此外,您可以在visual studio中创建xaml,然后复制/粘贴。这还允许您将可视化与功能分离。