Quantcast
Channel: Windows PowerShell Forum
Viewing all articles
Browse latest Browse all 2314

Animierten Ladebalken mit WindowsForms darstellen bzw. schließen

$
0
0

Hallo zusammen,

ich sitze momentan an einem Code, der eine (eventuell) auftretende Wartezeit in einem Script überbrücken soll. Je nach Client hat das Script bis zu einigen Sekunden Verzögerung, teilweise ist es augenblicklich ausgeführt.

Dazu wollte ich während der Wartezeit eine GUI anzeigen lassen, in der ein Ladebalken zu sehen ist. Write-Progress in der Konsole finde ich aber nicht besonders hübsch und so habe ich mich für ProgressBar von WindowsForms entschieden. Ich habe allerdings keinen Endzeitpunkt o.ä. festgelegt, da ich nicht weiß, wie das in meinem Fall zu realisieren wäre und ich meine, dass es anders besser ginge. Deswegen läuft der Ladebalken quasi ohne Ende immer wieder durch, bis er vom Script geschlossen wird. Leider bekomme ich die Ladebalken-GUI nicht geschlossen, und das Ganze sieht in der ISE mal wieder völlig anders aus als in der Konsolenausführung.

Zum Hauptskript: Das macht im Grunde nichts anderes, als über die WMI des Rechners alle Netzwerkkarten auszulesen und alle Realtek-Karten in eine Variable zu speichern. Über diese läuft dann eine Schleife, die die Properties AdapterType und MACAddress von jeder Karte überprüft und die Netzwerkkarte aktiviert, wenn beide Felder leer sind oder sie deaktivert, wenn beide Felder ausgefüllt sind. Das geschieht über die Enable()- bzw. Disable()-Methode. Über die ReturnValue-Eigenschaft der Methode selber überprüft das Script dann den Erfolg der Ausführung und gibt eine entsprechende Meldung aus.

Code:

if ($LANs){clv LANs}
if ($Ergebnis){clv Ergebnis}

$LANs = Get-WmiObject -Class Win32_NetworkAdapter | Where {$_.Name -like "*Realtek*"}
ForEach ($LAN in $LANs)
{
    if ($LAN -like "")
        {
            # Fehler, keine Netzwerkkarte gefunden
        }
    else
        {
            if ($LAN.MACAddress -like "" -and $LAN.AdapterType -like "")
            {
                $LANac = $LAN.Enable()
                $LANst = $LANac.ReturnValue
                if ($LANst -eq "0")
                    {
                        # erfolgreich aktiviert
                    }
                else
                    {
                        # Fehler, nicht aktiviert
                    }
            }
            else
            {
                $LANac = $LAN.Disable()
                $LANst = $LANac.ReturnValue
                if ($LANst -eq "0")
                    {
                        # erfolgreich deaktiviert
                    }
                else
                    {
                        # Fehler, nicht deaktiviert
                    }
            }
            # Endmeldung
        }
}

Bis die Endmeldung erscheint, soll eine GUI mit Ladebalken her. Ich habe mich für das endlose Durchlaufen entschieden, weil ich es für einfacher hielt, die GUI per Methode kurz vor oder nach Abschluss zu schließen statt einen Endzeitpunkt zu definieren. Falls das einfacher/sicherer geht, immer her damit! Deswegen der BorderStyle "Marquee", dazu sollen noch sowohl die drei Buttons oben in der Ecke deaktiviert sein; das Fenster soll mittig zu sehen sein und sich in der Größe nicht verändern lassen.

Code:

[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
 [Reflection.Assembly]::LoadWithPartialName("System.Drawing") | Out-Null
    $LoadForm = New-Object System.Windows.Forms.Form
    $LoadForm.Text = 'Loading'
    $LoadForm.Width = 350
    $LoadForm.Height = 144
    $LoadForm.MaximizeBox = $False
    $LoadForm.MinimizeBox = $False
    $LoadForm.ControlBox = $False
    $LoadForm.ShowIcon = $False
    $LoadForm.StartPosition = 1
    $LoadForm.Visible = $False

    $InText = New-Object System.Windows.Forms.Label
    $InText.Text = 'Loading...'
    $InText.Location = '18,26'
    $InText.Size = New-Object System.Drawing.Size(330,18)

    $progressBar1 = New-Object System.Windows.Forms.ProgressBar
    $ProgressBar1.Name = 'LoadingBar'
    $ProgressBar1.Style = "Marquee"
    $ProgressBar1.Location = "17,61"
    $ProgressBar1.Size = "300,18"
    $ProgressBar1.MarqueeAnimationSpeed = 20

    $LoadForm.Controls.Add($InText)
    $LoadForm.Controls.Add($ProgressBar1)
    
    $LoadForm.ShowDialog() | Out-Null

Problem: Das Fenster lässt sich nicht schließen. Ich habe es mit ShowDialog, Show und Visible = $True als Aufruf versucht.

ShowDialog(): Ich habe gelesen, dass sich so ein modales Dialog-Feld nur durch das Schließen-Symbol schließen lässt oder durch Events/EventHandler. Wenn ja, wie mache ich so etwas? ShowDialog wartet doch auf Eingaben, also stoppt das Skript. Ich müsste also vorher einen Timer einbauen. Ich kenne aber die Zeitspanne nicht... Außerdem müsste ich dann testen, ob es in der Konsole, mit der es später ausgeführt wird genauso aussieht.

Show(): Wenn ich die GUI per Show() aufrufe, läuft das Skript - soweit ich weiß - im Hintergrund weiter. Das hat aber zur Folge, dass selbst in der ISE nur das Fenster zu sehen ist, im Ladebalken bewegt sich leider nichts. Auch der Mauszeiger wird dann zum Ladekreis. Kann man den Ladebalken und die Animation alternativ als Job starten, sodass der im Hintergrund läuft und sich so animieren lässt? Als ich es versucht habe, habe ich die Konsolen-Version zu Gesicht bekommen... Und abgesehen von der eckigeren Optik, die nichts neues ist, war der Ladebalken ebenfalls nicht animiert und das Fenster trotz entsprechender Property (s.o.) verkleinerbar und vergrößerbar! Die powershell.exe führt das Ganzen später ja aus, also sollte das auch wie in der ISE nicht veränderbar sein.

.Visible = $True : Das Fenster wird geöffnet und kann nur durch .Visible = $False wieder geschlossen werden. Allerdings besteht hier dasselbe Problem wie bei Show(), kein animierter Balken etc.

So langsam bin ich mit meinem Latein am Ende. Bin für jede Idee dankbar.

Scriptex


Viewing all articles
Browse latest Browse all 2314


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>