スタートジョブタスクによって制御されたPowerShellフォームを閉じる

StackOverflow https://stackoverflow.com/questions/9427391

質問

ユーザーがネットワークプリンタをインストールできる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ウィンドウを除くことができる方法は誰でも知っていますか?

役に立ちましたか?

解決

メインスレッドの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
    }
}
.

他のヒント

この最初の回答は正しく、メインスレッド上のフォームを作成し、別のスレッドで長時間実行タスクを実行します。フォームが解除されるまでメインコードを実行していない理由は、フォームの「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
    }
}
.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top