在 Powershell 中运行 ProgressBar / GUI 的“简单”方法

在 Powershell 中运行 ProgressBar / GUI 的“简单”方法

花了大约 8 小时尝试不同的配置后,我已经没有主意了。(我认为这与 Powershell 的“单线程”特性有关;在 PERL 中,您可以执行“fork”,这可能会解决问题)

简而言之,用户单击“开始”将执行一个大约需要 20 秒才能运行的外部程序(由顶部的“do”循环表示)此时,GUI 看起来“冻结”了……所以我决定添加一个进度条。但当然,在处理“do”循环/外部程序时,“主”程序会暂停,直到前者终止(这会破坏整个对象)

我甚至尝试了第二种“形式”,将进度条放在其中,并通过“显示”运行它(显然,它应该在后台运行,因为它不接受用户交互......除了它仍然“冻结”进度条)

我考虑过使用动画,也就是忙指针...但似乎不能包含 GIF 动画,否则会带来更多问题!

也许它涉及“后台工作”......但这让我更加困惑!

前提是:

按下“开始”按钮将标签更改为“处理中”/删除“开始”按钮 --> 调用对话框(在功能范围内)来定位文件/保存位置/程序静默运行 15 - 30 秒,同时显示进度条(或动画)将标签更改为“完成”显示“确定”按钮以终止

注意:我发现我必须在函数中包含 ProgressBar,因为通过 AddRange 添加它,然后在函数中将其设置为“Visible”意味着它根本不显示

Add-Type -AssemblyName PresentationFramework
Add-Type -AssemblyName System.Drawing
[System.Windows.Forms.Application]::EnableVisualStyles()

function Extract(){
$ProgressBar              = New-Object System.Windows.Forms.ProgressBar
$ProgressBar.Location     = New-Object System.Drawing.Point(10,35)
$ProgressBar.Size         = New-Object System.Drawing.Size(460,40)
$ProgressBar.Style        = "Marquee"
$ProgressBar.MarqueeAnimationSpeed = 20
$main_form.Controls.Add($ProgressBar);

$Label.Font             = $procFont
$Label.ForeColor        ='red'
$Label.Text             ="Processing ..."
$ProgressBar.visible

$a=0;
    do{
    start-sleep(1)
    write-host $a
    $a++
    }while($a -lt 10)
$Label.Text               = "Process Complete"
$ProgressBar.Hide()
$StartButton.Hide()
$EndButton.Visible
}

$main_form                = New-Object System.Windows.Forms.Form
$main_form.Text           ='Subtitle Software Suite'
$main_form.BackColor      ='cyan'
$main_form.Width          = 520
$main_form.Height         = 180

$header                   = New-Object System.Drawing.Font("Verdana",13,[System.Drawing.FontStyle]([System.Drawing.FontStyle]::Bold))
$procFont                 = New-Object System.Drawing.Font("Verdana",20,[System.Drawing.FontStyle]([System.Drawing.FontStyle]::Bold))

$Label                    = New-Object System.Windows.Forms.Label
$Label.Font               = $header
$Label.ForeColor          ='blue'
$Label.Text               = "Audio extraction can take a long time"
$Label.Location           = New-Object System.Drawing.Point(10,10)
$Label.Width              = 480
$Label.Height             = 50

$StartButton              = New-Object System.Windows.Forms.Button
$StartButton.Location     = New-Object System.Drawing.Size(350,75)
$StartButton.Size         = New-Object System.Drawing.Size(120,50)
$StartButton.Text         = "Start"
$StartButton.height       = 40
$StartButton.BackColor    ='red'
$StartButton.ForeColor    ='white'
$StartButton.Add_click({EXTRACT});

$EndButton              = New-Object System.Windows.Forms.Button
$EndButton.Location     = New-Object System.Drawing.Size(350,75)
$EndButton.Size         = New-Object System.Drawing.Size(120,50)
$EndButton.Text         = "OK"
$EndButton.height       = 40
$EndButton.BackColor    ='red'
$EndButton.ForeColor    ='white'
$EndButton.DialogResult = [System.Windows.Forms.DialogResult]::OK

$main_form.Controls.AddRange(($Label,$StartButton,$EndButton))

$main_form.StartPosition = "manual"
$main_form.Location = New-Object System.Drawing.Size(500, 300)
$result=$main_form.ShowDialog() 

if ($result -eq [System.Windows.Forms.DialogResult]::OK){
$main_form.Close()
}

答案1

以下是使用需要 20 秒才能完成的作业的示例。它用于DoEvents()防止 GUI 冻结,这并非毫无意义问题但可能适合您的需要。

Add-Type -AssemblyName PresentationFramework
Add-Type -AssemblyName System.Drawing
[System.Windows.Forms.Application]::EnableVisualStyles()

$jobScript =
{
    Start-Sleep -Seconds 20
}


function Extract() {
    $ProgressBar = New-Object System.Windows.Forms.ProgressBar
    $ProgressBar.Location = New-Object System.Drawing.Point(10, 35)
    $ProgressBar.Size = New-Object System.Drawing.Size(460, 40)
    $ProgressBar.Style = "Marquee"
    $ProgressBar.MarqueeAnimationSpeed = 20

    $main_form.Controls.Add($ProgressBar);

    $Label.Font = $procFont
    $Label.ForeColor = 'red'
    $Label.Text = "Processing ..."
    $ProgressBar.visible

    $job = Start-Job -ScriptBlock $jobScript
    do { [System.Windows.Forms.Application]::DoEvents() } until ($job.State -eq "Completed")
    Remove-Job -Job $job -Force


    $Label.Text = "Process Complete"
    $ProgressBar.Hide()
    $StartButton.Hide()
    $EndButton.Visible
}

$main_form = New-Object System.Windows.Forms.Form
$main_form.Text = 'Subtitle Software Suite'
$main_form.BackColor = 'cyan'
$main_form.Width = 520
$main_form.Height = 180

$header = New-Object System.Drawing.Font("Verdana", 13, [System.Drawing.FontStyle]([System.Drawing.FontStyle]::Bold))
$procFont = New-Object System.Drawing.Font("Verdana", 20, [System.Drawing.FontStyle]([System.Drawing.FontStyle]::Bold))

$Label = New-Object System.Windows.Forms.Label
$Label.Font = $header
$Label.ForeColor = 'blue'
$Label.Text = "Audio extraction can take a long time"
$Label.Location = New-Object System.Drawing.Point(10, 10)
$Label.Width = 480
$Label.Height = 50

$StartButton = New-Object System.Windows.Forms.Button
$StartButton.Location = New-Object System.Drawing.Size(350, 75)
$StartButton.Size = New-Object System.Drawing.Size(120, 50)
$StartButton.Text = "Start"
$StartButton.height = 40
$StartButton.BackColor = 'red'
$StartButton.ForeColor = 'white'
$StartButton.Add_click( { EXTRACT });

$EndButton = New-Object System.Windows.Forms.Button
$EndButton.Location = New-Object System.Drawing.Size(350, 75)
$EndButton.Size = New-Object System.Drawing.Size(120, 50)
$EndButton.Text = "OK"
$EndButton.height = 40
$EndButton.BackColor = 'red'
$EndButton.ForeColor = 'white'
$EndButton.DialogResult = [System.Windows.Forms.DialogResult]::OK

$main_form.Controls.AddRange(($Label, $StartButton, $EndButton))

$main_form.StartPosition = "manual"
$main_form.Location = New-Object System.Drawing.Size(500, 300)
$result = $main_form.ShowDialog()

if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
    $main_form.Close()
}

相关内容