2

我的任务是构建一个带有 GUI 的 powershell 脚本,使用户能够安装网络打印机。我已经成功地做到了,但我无法满足在安装打印机时向用户显示“请稍候”窗口的要求。如果我从主线程切换到窗口,则 GUI 挂起。如果我将显示窗口转移到单独的工作中,我将永远无法再次关闭窗口。这是我的尝试:

$waitForm = New-Object 'System.Windows.Forms.Form'

$CloseButton_Click={

    # open "please wait form"
    Start-Job -Name waitJob -ScriptBlock $callWork -ArgumentList $waitForm

    #perform long-running (duration unknown) task of adding several network printers here
    $max = 5
    foreach ($i in $(1..$max)){
        sleep 1 # lock up the thread for a second at a time
    }

    # close the wait form - doesn't work. neither does remove-job
    $waitForm.Close()
    Remove-Job -Name waitJob -Force
}

$callWork ={

    param $waitForm

    [void][reflection.assembly]::Load("System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
    $waitForm = New-Object 'System.Windows.Forms.Form'

    $labelInstallingPrintersPl = New-Object 'System.Windows.Forms.Label'
    $waitForm.Controls.Add($labelInstallingPrintersPl)
    $waitForm.ClientSize = '502, 103'
    $labelInstallingPrintersPl.Location = '25, 28'
    $labelInstallingPrintersPl.Text = "Installing printers - please wait..."

    $waitForm.ShowDialog($this)
} 

有谁知道在长时间运行的任务结束后如何关闭 $waitForm 窗口?

4

3 回答 3

2

您可以尝试在主线程上运行 Windows 窗体对话框并在后台作业中执行实际工作:

Add-Type -Assembly System.Windows.Forms

$waitForm = New-Object 'System.Windows.Forms.Form'
$labelInstallingPrintersPl = New-Object 'System.Windows.Forms.Label'
$waitForm.Controls.Add($labelInstallingPrintersPl)
$waitForm.ClientSize = '502, 103'
$labelInstallingPrintersPl.Location = '25, 28'
$labelInstallingPrintersPl.Text = "Installing printers - please wait..."
$waitForm.ShowDialog($this)

Start-Job -ScriptBlock $addPrinters | Wait-Job

$waitForm.Close()

$addPrinters = {
    $max = 5
    foreach ($i in $(1..$max)) {
        sleep 1 # lock up the thread for a second at a time
    }
}
于 2012-02-24T10:47:50.270 回答
2

第一个答案是正确的,在主线程上创建表单并在单独的线程上执行长时间运行的任务。直到关闭表单后才执行主代码的原因是因为您使用的是表单的“ShowDialog”方法,该方法会拖拉后续代码执行,直到表单关闭。

而是使用“show”方法,代码执行将继续,您可能应该包含一些事件处理程序来处理表单

Add-Type -Assembly System.Windows.Forms

$waitForm = New-Object 'System.Windows.Forms.Form'
$labelInstallingPrintersPl = New-Object 'System.Windows.Forms.Label'
$waitForm.Controls.Add($labelInstallingPrintersPl)
$waitForm.ClientSize = '502, 103'
$labelInstallingPrintersPl.Location = '25, 28'
$labelInstallingPrintersPl.Text = "Installing printers - please wait..."

$waitForm.Add_FormClosed({
$labelInstallingPrintersPl.Dispose()
$waitForm.Dispose()
})

$waitForm.Show($this)

Start-Job -ScriptBlock $addPrinters | Wait-Job

$waitForm.Close()

$addPrinters = {
    $max = 5
    foreach ($i in $(1..$max)) {
        sleep 1 # lock up the thread for a second at a time
    }
}
于 2012-08-22T03:07:19.487 回答
0

Windows.Forms.Progressbar添加到主 GUI 窗口怎么样?添加打印机时逐步更新其值,以便用户看到应用程序正在运行。

于 2012-02-24T08:28:18.623 回答