I tried to create an async Progress bar:
Code: Select all
function Show-WaitDialog {
<#
.SYNOPSIS
Shows a wait Dialog
.DESCRIPTION
Shows a wait dialog as foreground window.
Must be closed manually!
.PARAMETER Title
Dialog Title
.PARAMETER Message
Dialog Message
.PARAMETER CloseMe
Closes the Dialog
.EXAMPLE
PS C:\> Show-Wait -Title "Mytitle" -Message "Please wait for the fucntion to finish..."
.NOTES
0.0.1 20.02.2017 CER Description
#>
[CmdletBinding()]
param
(
[string]$Title = "Working...",
[Parameter(ValueFromRemainingArguments = $true)][string]$Message = "Please Wait...",
[switch]$CloseMe
)
$strSB = @'
param($Title,$Message)
# Benötigte Assemblies laden
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
[Void][Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms.VisualStyles')
# Progress Form erstellen
$ProgressForm = New-Object System.Windows.Forms.Form
$ProgressForm.Text = $Title
$ProgressForm.Width = 350
$ProgressForm.Height = 200
$ProgressForm.MaximizeBox = $False
$ProgressForm.MinimizeBox = $False
$ProgressForm.ControlBox = $False
$ProgressForm.ShowIcon = $False
$ProgressForm.StartPosition = 1
$ProgressForm.Visible = $False
$ProgressForm.FormBorderStyle = 'FixedDialog'
#$ProgressForm.WindowState = "Normal"
# Textfeld erzeugen
$InText = New-Object System.Windows.Forms.Label
$InText.Text = $Message
$InText.Location = '18,26'
$InText.Size = New-Object System.Drawing.Size(330, 38)
# Progressbar erzeugen
$progressBar1 = New-Object System.Windows.Forms.ProgressBar
$ProgressBar1.Name = 'LoadingBar'
$ProgressBar1.Style = 'Marquee'
$ProgressBar1.Location = '17,101'
$ProgressBar1.Size = '300,18'
$ProgressBar1.MarqueeAnimationSpeed = 40
# Textfeld in die Form einfügen
$ProgressForm.Controls.Add($InText)
# Progressbar in die Form einfügen
$ProgressForm.Controls.Add($ProgressBar1)
# Speichern der Form in die Hashtable
$sharedData.Form = $ProgressForm
$ProgressForm.TopMost = $true
[System.Windows.Forms.Application]::EnableVisualStyles()
[System.Windows.Forms.Application]::Run($ProgressForm)
$ProgressForm.TopMost = $true
#[System.Windows.Forms.Application]::DoEvents()
'@
$objSB = [Scriptblock]::Create($strSB)
if (-not $closeMe.Ispresent) {
# Hashtable für Datenaustausch zwischen den Threads
$script:sharedData = [HashTable]::Synchronized(@{
})
$Script:sharedData.Form = $Null
# Runspace für die Progress Form mit der Hashtable zum synchronisieren vorbereiten
$newRunspace = [RunSpaceFactory]::CreateRunspace()
$newRunspace.ApartmentState = 'STA'
$newRunspace.ThreadOptions = 'ReuseThread'
$null = $newRunspace.Open()
$newRunspace.SessionStateProxy.setVariable('sharedData', $sharedData)
# Thread für die Progress Form (eine eigene asynchrone Powershell)
# mit dem vorbereiteten Runspace starten und die Function 'ShowProgressForm' als Script übergeben
$script:PS = [PowerShell]::Create()
$PS.Runspace = $newRunspace
#$Scriptcall = $PS.AddScript($Function:ShowProgressForm)
$Scriptcall = $PS.AddScript($objSB)
$null = $Scriptcall.AddParameter("Title", $Title);
$null = $Scriptcall.AddParameter("Message", $Message);
# Thread (Runspace) für die Progress Form asynchron starten
$Script:AsyncResult = $PS.BeginInvoke()
} else {
#Write-Host "closing..."
# Progress Form befindet sich in der Synchronized Hashtable
# über die Hashtable kann die Form im einem anderen Thread angesprochen werden
If ($sharedData.Form) {
$sharedData.Form.close()
}
# Thread (Runspace) für die Progress Form asynchron beenden
$PS.Endinvoke($AsyncResult)
# Thread (Runspace) für die Progress Form zerstören
$PS.dispose()
try {
$newRunspace.CloseAsync()
$newRunspace.Close()
} catch {}
}
}
If it runs as a Powershell Studio compiled Exe GUI the GUI closes normally but the Exe stays active (get-process).
Does anybody know why and/or what i can do to close the exe itself?
Thanks
Peter