花了大约 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()
}