Отклонить форму Powershell, контролируемую заданием запуска - PullRequest
2 голосов
/ 24 февраля 2012

Мне было поручено создать сценарий powershell с графическим интерфейсом, который позволяет пользователям устанавливать сетевые принтеры.Мне удалось это сделать, но я не могу выполнить требование, чтобы пользователю отображалось окно «Пожалуйста, подождите», пока принтеры устанавливаются.Если я переключаюсь на окно из основного потока, графический интерфейс зависает.Если я перейду с показом окна к отдельной работе, я больше никогда не смогу закрыть окно.Вот моя попытка:

$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 после завершения долгосрочной задачи?

Ответы [ 3 ]

2 голосов
/ 24 февраля 2012

Вы можете попробовать запустить диалоговое окно Windows Forms в главном потоке и выполнить фактическую работу в фоновом режиме:

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
    }
}
2 голосов
/ 22 августа 2012

Этот первый ответ был правильным, создайте форму в главном потоке и выполните долгосрочное задание в отдельном потоке. Причина, по которой он не выполняет основной код до тех пор, пока форма не будет закрыта, заключается в том, что вы используете метод '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
    }
}
0 голосов
/ 24 февраля 2012

Как насчет добавления Windows.Forms.Progressbar в главное окно графического интерфейса?Обновляйте его значение шаг за шагом при добавлении принтеров, чтобы пользователи увидели, что приложение работает.

...