PowerShell WPF GUI Auswahl - für PowerShell-Parameter

 

Mit folgendem PowerShell-Beispiel kann sehr einfach eine GUI-Auswahl für bestehende PowerShell Skripts erzeugt werden.

Das Script liest die möglichen Switch-Parameter eines anderen Skripts und erzeugt daraus eine GUI zur Auswahl bestimmter Parameter:

Parameter.ps1

Folgendes PowerShell-Skript enthält die Switch-Parameter:

[CmdletBinding()]
Param(
  [Parameter(Mandatory=$false)]
   [switch]$Option,
	
   [Parameter(Mandatory=$false)]
   [switch]$nochEineOption,

   [Parameter(Mandatory=$false)]
   [switch]$dritteOption,

   [Parameter(Mandatory=$false)]
   [switch]$vierteOption
)
write-host $Option
write-host $nochEineOption
write-host $dritteOption
write-host $vierteOption
timeout 5

Automatisches Auslesen von Switch-Parametern

Das GUI - Skript liest die möglichen Parameter und erzeugt daraus eine GUI. In diesem Beispiel werden Parameter die "Option" in deren Namen enthalten, verwendet. Nachdem das Skript gestartet wurde, kann das Skript Parameter.ps1 mit einem der ausgelesenen Parametern ausgeführt werden.

$parameterscript=".\parameter.ps1"

#XAML Code kann zwischen @" und "@ ersetzt werden:
[xml]$XAML = @"
<Window x:Class="WpfApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication"
mc:Ignorable="d"
Title="MainWindow" Height="768" Width="1024">

        <StackPanel x:Name="StackPanel" Margin = "50,50,50,50">         
        <Label x:Name="label" Content="please select an Option" HorizontalAlignment="Left"/>                                        
        </StackPanel>
</Window>
"@ -replace 'mc:Ignorable="d"','' -replace "x:N",'N' -replace '^<Win.*', '<Window' #-replace wird benötigt, wenn XAML aus Visual Studio kopiert wird.
#XAML laden
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
try{$Form=[Windows.Markup.XamlReader]::Load( (New-Object System.Xml.XmlNodeReader $XAML) )}
catch{Write-Host "Windows.Markup.XamlReader konnte nicht geladen werden. Mögliche Ursache: ungültige Syntax oder fehlendes .net"}
$StackPanel = $Form.FindName("StackPanel")

function add_button($strLabel) {
        $objButton = New-Object System.Windows.Controls.Button
        $objButton.Content = $strLabel
        $objButton.Background = 'Blue'
        $objButton.Foreground = 'White'
        $objButton.margin = '5'
        $objButton.height = '40'
        $objButton.Name = $strLabel
        $objButton.Add_Click({
                write-host "$($this.content) pressed"
                $Form.FindName("label").Content= "$($this.content) gestartet"
                $Form.Close()
                invoke-expression -Command ("$parameterscript -$($this.content)")
        }) 
        #insert it into the StackPanel
        $StackPanel.Children.Insert(($StackPanel.Children.count),$objButton)   

} 

#Read Parameters and add the Buttons:
$parameters=((get-command $parameterscript).parameters).Keys
foreach ($parameter in $parameters) {if ($parameter -like "*Option*") {add_button $parameter}}

#Fenster anzeigen:
$Form.ShowDialog()

Nach dem Start des Skripts lädt die GUI mit den ausgelesenen Optionen:

Bei Auswahl eines Parameters in der GUI wird dieser an das Parameter.ps1-Skript übergeben:

PS C:\temp> .\dynprop.ps1
Option pressed
True
False
False
False

Alternativ: Definition der externen Skripts, Parameter und der Buttons in einem Object-Array

Mit Folgendem Skript können die Auswahl und die entsprechenden Parameter definiert werden:

#Variables
$script:GUIElements = @(
    [pscustomobject]@{
        script=".\parameter.ps1";parameters="-Option -nochEineOption";text="Skript 1 mit den angegebenen Parametern"
    },
    [pscustomobject]@{
        script=".\parameter.ps1";parameters="-nochEineOption";text="Skript 1 mit alternativen Parametern"
    },
    [pscustomobject]@{
        script=".\Skript2.ps1";parameters="";text="Skript 2 ohne Parameter"
    }
)

#Lyout:XAML Code kann zwischen @" und "@ ersetzt werden:
[xml]$XAML = @"
<Window x:Class="WpfApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication"
mc:Ignorable="d"
Title="Select an Item" Height="768" Width="1024" Background="#cccccc">
    <Window.Resources>
      <Style TargetType="Button">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border Name="border" BorderThickness="1" BorderBrush="Black" CornerRadius="7" Padding="7" Background="{TemplateBinding Background}">
                            <ContentPresenter HorizontalAlignment="Left" VerticalAlignment="Center" />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Opacity" Value="0.3" />
                                <Setter Property="Foreground" Value="#ffffff"/>
                                <Setter Property="Background" Value="#000000"/>
                                <Setter Property="BorderBrush" Value="#ffffff"/>
                        </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
      </Style>
    </Window.Resources>
        <StackPanel x:Name="StackPanel" Margin = "50,50,50,50">   
        <Label x:Name="label" Content="Auswahl:" HorizontalAlignment="Left"/>                                        
        </StackPanel>
</Window>
"@ -replace 'mc:Ignorable="d"','' -replace "x:N",'N' -replace '^<Win.*', '<Window' #-replace wird benötigt, wenn XAML aus Visual Studio kopiert wird.
#XAML laden
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
try{$Form=[Windows.Markup.XamlReader]::Load( (New-Object System.Xml.XmlNodeReader $XAML) )}
catch{Write-Host "Windows.Markup.XamlReader konnte nicht geladen werden. Mögliche Ursache: ungültige Syntax oder fehlendes .net"}
$StackPanel = $Form.FindName("StackPanel")

function add_button($strLabel) {
        $objButton = New-Object System.Windows.Controls.Button
        $objButton.Content = $strLabel
        $objButton.margin = '5'
        $objButton.height = '40'
        $objButton.Name = $(($strLabel) -replace "[^a-zA-Z1-9]")
        $objButton.Add_Click({
                write-host "$($this.content) pressed"
                $Form.FindName("label").Content= "$($this.content) gestartet"

                foreach ($Element in $script:GUIElements) {
                    if ($($Element.text) -eq $($this.content)){
                    $command= "$($Element.script) $($Element.parameters)"
                    write-host "starting command $command"
                    $Form.Close()
                    invoke-expression -Command $command
                    }
                }

        }) 
        #insert it into the StackPanel
        $StackPanel.Children.Insert(($StackPanel.Children.count),$objButton)   

} 

foreach ($Element in $script:GUIElements) {
add_button $Element.text
}

#Fenster anzeigen:
$Form.ShowDialog()

 

positive Bewertung({{pro_count}})
Beitrag bewerten:
{{percentage}} % positiv
negative Bewertung({{con_count}})

DANKE für deine Bewertung!

Fragen / Kommentare


(sortiert nach Bewertung / Datum) [alle Kommentare(neueste zuerst)]

✍anonym
19.05.2020 11:43
Vielen Dank dafür!

Aber eine Frage:
Wie ist es den möglich in dem letzten Beispiel ein Bild (Pfad auf Festplatte oder als Web-Link) dort hinzuzufügen?