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?

È stato utile?

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
    }
}
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top