Licenziare una forma PowerShell controllata da un'attività iniziale-lavoro
-
12-11-2019 - |
Domanda
Sono stato incaricato di creare uno script PowerShell con una GUI che consente agli utenti di installare stampanti di rete.Sono riuscito a farlo con successo, ma non riesco a soddisfare il requisito che l'utente venga mostrato una finestra "Attendi" mentre le stampanti vengono installate.Se passerò alla finestra dal filo principale, la GUI si blocca.Se mi muovo a mostrare la finestra a un lavoro separato, non sono mai in grado di chiudere di nuovo la finestra.Ecco il mio tentativo:
$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)
}
.
Qualcuno sa come posso licenziare la finestra $ waitform quando è conclusa la commissione di lunga durata?
Soluzione
È possibile provare a eseguire la finestra di dialogo Forme di Windows sul thread principale e eseguire il lavoro effettivo in un lavoro di sfondo:
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
}
}
. Altri suggerimenti
Questa prima risposta è stata corretta, creare il modulo sul filettatura principale ed eseguire l'attività di esecuzione lunga su un filo separato.Il motivo per cui non esegue il codice principale fino a quando il modulo viene licenziato è perché stai utilizzando il metodo 'showDialog' del modulo, questo metodo ha coltivato l'esecuzione del codice successiva fino a quando il modulo è chiuso.
Utilizzare invece il metodo 'Mostra', l'esecuzione del codice continuerà, dovresti probabilmente includere alcuni gestori di eventi per smaltire il modulo
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
}
}
.