Pregunta

Me han encargado de construir un script de PowerShell con una GUI que permite a los usuarios instalar impresoras de red.También he logrado hacerlo, pero no puedo cumplir con el requisito de que el usuario se le muestre una ventana "Por favor, espere", mientras que las impresoras se instalan.Si cambia a la ventana del hilo principal, la GUI cuelga.Si me muevo mostrando la ventana a un trabajo separado, nunca más puedo cerrar la ventana.Aquí está mi intento:

$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)
} 

¿Alguien sabe cómo puedo descartar la ventana de $ Waitform cuando la tarea de larga duración ha concluido?

¿Fue útil?

Solución

Podría intentar ejecutar el cuadro de diálogo Formularios de Windows en el hilo principal y hacer el trabajo real en un trabajo de fondo:

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

Otros consejos

Esta primera respuesta fue correcta, cree el formulario en el hilo principal y realice la tarea de ejecución larga en un hilo separado.La razón por la que no ejecuta el código principal hasta que se desestime el formulario es porque está utilizando el método 'ShowDialog' del formulario, este método ha surgido la ejecución posterior del código hasta que el formulario está cerrado.

Utilice el método 'Mostrar', la ejecución del código continuará, probablemente debería incluir algunos manipuladores de eventos para deshacerse del formulario

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top