PowerShell: Графический интерфейс via XML


Powershell позволяет делать графический интерфейс даже через XML (XAML)
Для работы формами XML сама оболочка должна быть запущена с ключом sta

> powershell -sta

Итак, файл формы (его можно сгенерировать в VisualStudio) form1.xml

<Window 
 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" 
 Title="Заголовочек" Height="146" Width="205">
 <Grid Height="103" Width="180">
  <Button Content="Кнопочка А" Height="23" HorizontalAlignment="Left" 
     Margin="12,12,0,0" Name="button1" VerticalAlignment="Top" Width="75" />
  <Button Content="Кнопочка Б" Height="23" HorizontalAlignment="Left" 
     Margin="93,12,0,0" Name="button2" VerticalAlignment="Top" Width="75" />
  <TextBlock Height="23" HorizontalAlignment="Left" 
     Margin="12,41,0,0" Name="textBlock1" Text="Текст" VerticalAlignment="Top" Width="156" />
  <ComboBox Height="23" HorizontalAlignment="Left" 
     Margin="12,70,0,0" Name="comboBox1" VerticalAlignment="Top" Width="156">
    <ComboBoxItem Content="Выбор 1" />
    <ComboBoxItem Content="Выбор 2" />
  </ComboBox>
 </Grid>
</Window>

И, собственно, скрипт Powershell form1.ps1:

Add-Type -Assembly PresentationFramework
function add($control, $children)
{
   $children | %{ $control.Children.Add($_)} | Out-Null
   $control
}
$w = New-Object System.Windows.Window -prop @{
    SizeToContent = [System.Windows.SizeToContent]::WidthAndHeight;
    Content = add (New-Object System.Windows.Controls.StackPanel) @(        
        add (New-Object System.Windows.Controls.StackPanel -prop @{ Orientation =
            [System.Windows.Controls.Orientation]::Horizontal}) @(
               New-Object System.Windows.Controls.Button -prop @{Content="Кнопочка A";}
               New-Object System.Windows.Controls.Button -prop @{Content="Кнопочка Б";}
        )
        New-Object System.Windows.Controls.TextBlock -prop @{Text="Текст"}        
        New-Object System.Windows.Controls.Combobox -prop @{ItemsSource=@("Выбор 1", "Выбор 2")}
    );    
}
$w.ShowDialog()

Для простого чтения XML на самом деле достаточно гораздо более простого скрипта form1.ps1:

Add-Type -AssemblyName presentationframework
$xaml = [xml](Get-Content ".\form1.xml")
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
$Form=[Windows.Markup.XamlReader]::Load( $reader )
$Form.ShowDialog() | out-null