在 Powershell 中将动画 .gif 导入 Windows.Forms

Importing an animated .gif into Windows.Forms in Powershell

我是 Powershell 的新手,运行 对此问题很感兴趣。我有一个很长的自动安装脚本,它通过 MySQL install/account 设置和其他 .msi 运行。

当用户等待脚本完成时,我有这个 "Please Wait" 提示显示,在图片框中包含一个旋转的风车 .gif。

问题是,如果我将 form.visible 设置为 $true 并稍后在脚本中将其关闭,那么 .gif 本身将不会移动。它显示但失去了它的动画。如果我将 form.visible 更改为 "false" 并通过添加 form.showdialog() 参数将表单更改为模态,动画在 .gif 中是完美的,但脚本停止并且只能在之后继续window 已关闭。有没有办法让脚本在不丢失 .gif 动画的情况下前进?请帮忙。出于某种原因,我发现很少有关于 powershell 和 .gif 的论坛。这是表单的代码。

$Form = New-Object system.Windows.Forms.Form
$Form.Location= New-Object System.Drawing.Size(100,100)
$Form.Size= New-Object System.Drawing.Size(550,170)
$Form.StartPosition = "Manual"
$Form.Visible=$true
$Form.Enabled = $true


[reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
$file = (get-item 'PathToMyGifFile')
$img = [System.Drawing.Image]::Fromfile($file);

[System.Windows.Forms.Application]::EnableVisualStyles();

$pictureBox = new-object Windows.Forms.PictureBox
$pictureBox.Location = New-Object System.Drawing.Size(0,1)
$pictureBox.Size = New-Object System.Drawing.Size(100,80)
$pictureBox.Image = $img
$Form.controls.add($pictureBox)

$Label1 = New-Object System.Windows.Forms.Label
$Label1.Text = "Please wait for Installation to complete"
$Label1.Location= New-Object System.Drawing.Size(110,35) 
$Label1.Size = New-Object System.Drawing.Size(400,25) 
$Label1Font = New-Object System.Drawing.Font("Tahoma",10,
[System.Drawing.FontStyle]::Bold)

$Label1.Font = $Label1Font
$Label1.BackColor = "white"
$Form.Controls.Add($Label1)

$Label2 = New-Object System.Windows.Forms.Label
$Label2.Text = "This may take several minutes . . ."
$Label2.Location= New-Object System.Drawing.Size(120,60) 
$Label2.Size = New-Object System.Drawing.Size(370,75)
$Label2Font = New-Object System.Drawing.Font("Tahoma",10,
[System.Drawing.FontStyle]::Regular)

$Label2.Font = $Label2Font
$Label2.BackColor = "white" 
$Form.Controls.Add($Label2)

$BackDrop = New-Object System.Windows.Forms.Label
$BackDrop.Location = New-Object System.Drawing.Size(0,0) 
$BackDrop.Size = New-Object System.Drawing.Size(550,150) 
$BackDrop.BorderStyle = [System.Windows.Forms.BorderStyle]::FixedSingle;
$BackDrop.BackColor = [System.Drawing.Color]::White

$Form.Controls.Add($WaitBackGroundBox)
$Form.Topmost = $True
[void] $Form.ShowDialog() # If absent, animation is lost. If present 
                          # (combined with form.visible = $false), script 
                          # halts until the form itself is closed.

为什么不使用在 WinForms 中实现的 progressBar 控件?

随着 "Marquee" 动画速度,进度条将像 "Please Wait" 一样运行并且不会停止并且更容易添加到您的脚本而不是 gif。

在 Winforms 中使用 progressBar 的例子:https://www.sapien.com/blog/2011/07/14/primalforms-2011-spotlight-on-the-progressbar-control/

我找到了一个带有变通方法的线程,它创建了一个新的运行空间并在其中打开了表单。这样 .gif 就可以正常运行,您可以随时在代码中发出 form.close() 命令。这会派上用场,以防万一有人想将 .gif 用于 Please Wait 指示器以外的其他内容。从该站点发布:

https://www.vistax64.com/powershell/16998-howto-create-windows-form-without-stopping-script-processing.html

$Form = New-Object system.Windows.Forms.Form
$Form.Location= New-Object System.Drawing.Size(100,100)
$Form.Size= New-Object System.Drawing.Size(550,170)
$Form.StartPosition = "Manual"
$Form.Visible=$false
$Form.Enabled = $true
$Form.Add_Shown({$Form.Activate()})

[reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
$file = (get-item 'C:\path_to_your_gif.gif')
$img = [System.Drawing.Image]::Fromfile($file);

[System.Windows.Forms.Application]::EnableVisualStyles();

$pictureBox = new-object Windows.Forms.PictureBox
$pictureBox.Location = New-Object System.Drawing.Size(0,1)
$pictureBox.Size = New-Object System.Drawing.Size(100,80)
$pictureBox.Image = $img
$Form.controls.add($pictureBox)

$Label = New-Object System.Windows.Forms.Label
$Label.Text = "Please wait for Installation to complete"
$Label.Location= New-Object System.Drawing.Size(110,35) 
$Label.Size = New-Object System.Drawing.Size(400,25) 
$LabelFont = New-Object System.Drawing.Font("Tahoma",10,
[System.Drawing.FontStyle]::Bold)
$Label.Font = $PleaseWaitLabelFont
$Label.BackColor = "white"
$Form.Controls.Add($WaitLabel)

$WaitForm.Topmost = $True

$rs = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
$rs.Open()
$rs.SessionStateProxy.SetVariable("Form", $Form)
$data = [hashtable]::Synchronized(@{text=""})
$rs.SessionStateProxy.SetVariable("data", $data)
$p = $rs.CreatePipeline({ [void] $Form.ShowDialog()})
$p.Input.Close()
$p.InvokeAsync()

## Enter the rest of your script here while you want the form to display

$WaitForm.close()
$rs.close()