如何将XAML代码正确导入PowerShell



我正在尝试使用PowerShell中的VisualStudio创建的GUI。

因此,我必须将XAML代码从VisualStudio导入到我的脚本

这是我到目前为止得到的:

[xml]$XAML = @"
<Window 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    <Grid Margin="0,0,2,0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0*"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Label Name="Enter_Hostname_Label" Content="Enter Hostname:" HorizontalAlignment="Left" Height="26" Margin="9,19,0,0" VerticalAlignment="Top" Width="98" Grid.Column="1"/>
        <TextBox Name="Textbox" HorizontalAlignment="Left" Height="21" Margin="15,43,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="119" Grid.Column="1"/>
        <Label Name="Available_Hostnames_Label" Content="Available Hostnames:" HorizontalAlignment="Left" Height="26" Margin="11,83,0,0" VerticalAlignment="Top" Width="125" Grid.Column="1"/>
        <ListBox Name="Listbox" Grid.ColumnSpan="2" HorizontalAlignment="Left" Height="141" Margin="15,108,0,0" VerticalAlignment="Top" Width="119"/>
        <Button Name="Continue_Button" Grid.ColumnSpan="2" Content="Continue" HorizontalAlignment="Left" Height="21" Margin="143,108,0,0" VerticalAlignment="Top" Width="84" Click="Button_Click"/>
        <Button Name="Search_Button" Grid.ColumnSpan="2" Content="Search" HorizontalAlignment="Left" Height="21" Margin="143,43,0,0" VerticalAlignment="Top" Width="84" Click="Button_Click"/>
    </Grid>
</Window> 
"@ 
[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"
}
#Fenster anzeigen:
$Form.ShowDialog()

但是我收到一条错误消息,上面写着:该值不能转换为类型的" system.xml.xmldocument"。错误:"不允许名称从符号开始

,但是我无法更改它,因为如果我这样做的GUI代码将不再起作用

我在互联网上搜索了很多,但找不到解决方案。似乎对这样的每个人都有用

有人可以告诉我我的脚本怎么了?

有关如何使用Visual Studio创建PowerShell Gui的完整系列。

使用Visual Studio在几分钟内创建PowerShell Guis - 一个新的Hope

https://foxdeploy.com/2015/04/04/10/part-i-creating-powershell-guis-guis-in-minutes-in-minutes-usis-usis-usis-visual-bisual-studio-a-a-new-new-new-hope

https://foxdeploy.com/2015/04/16/part-ii-deploying-powershell-guis-guis-in-in-minutes-usis-using-using-usis-visual-studio

有很多屏幕截图,并逐步说明可以执行此操作。因此不能在这里发布。当涉及XAML时,作者提供了此样本:

# If you want to use my example as the base for your GUI, you can copy this right into Visual Studio:
<Window x:Class="FoxDeploy.Window1" 
    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:Azure" 
    mc:Ignorable="d" 
    Title="FoxDeploy Awesome GUI" Height="524.256" Width="332.076">    
    <Grid Margin="0,0,45,0">
        <Image x:Name="image" HorizontalAlignment="Left" Height="100" Margin="24,28,0,0" VerticalAlignment="Top" Width="100" Source="C:UsersStephenDropboxDocsblogfoxdeploy favicon.png"/>
        <TextBlock x:Name="textBlock" HorizontalAlignment="Left" Height="100" Margin="174,28,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="282" FontSize="16"><Run Text="Use this tool to find out all sorts of useful disk information, and also to get rich input from your scripts and tools"/><InlineUIContainer>
                <TextBlock x:Name="textBlock1" TextWrapping="Wrap" Text="TextBlock"/>
            </InlineUIContainer></TextBlock>
        <Button x:Name="button" Content="OK" HorizontalAlignment="Left" Height="55" Margin="370,235,0,0" VerticalAlignment="Top" Width="102" FontSize="18.667"/>
        <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="35" Margin="221,166,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="168" FontSize="16"/>
        <Label x:Name="label" Content="UserName" HorizontalAlignment="Left" Height="46" Margin="56,162,0,0" VerticalAlignment="Top" Width="138" FontSize="16"/>
</Grid>
</Window>

将其导入PowerShell

#Your XAML goes here :)
$inputXML = @"
<Window x:Class="Azure.Window1" 
    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:Azure" 
    mc:Ignorable="d" 
    Title="FoxDeploy Awesome GUI" Height="524.256" Width="332.076">
    <Grid Margin="0,0,174,0">
    </Grid>
</Window>
"@ 
$inputXML = $inputXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N' -replace '^<Win.*', '<Window'
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$XAML = $inputXML
#Read XAML
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
try{
    $Form=[Windows.Markup.XamlReader]::Load( $reader )
}
catch{
    Write-Warning "Unable to parse XML, with error: $($Error[0])`n Ensure that there are NO SelectionChanged or TextChanged properties in your textboxes (PowerShell cannot process them)"
    throw
}
#===========================================================================
# Load XAML Objects In PowerShell
#===========================================================================
$xaml.SelectNodes("//*[@Name]") | %{"trying item $($_.Name)";
    try {Set-Variable -Name "WPF$($_.Name)" -Value $Form.FindName($_.Name) -ErrorAction Stop}
    catch{throw}
    }
Function Get-FormVariables{
if ($global:ReadmeDisplay -ne $true){Write-host "If you need to reference this display again, run Get-FormVariables" -ForegroundColor Yellow;$global:ReadmeDisplay=$true}
write-host "Found the following interactable elements from our form" -ForegroundColor Cyan
get-variable WPF*
}
Get-FormVariables
#===========================================================================
# Use this space to add code to the various form elements in your GUI
#===========================================================================

#Reference 
#Adding items to a dropdown/combo box
    #$vmpicklistView.items.Add([pscustomobject]@{'VMName'=($_).Name;Status=$_.Status;Other="Yes"})
#Setting the text of a text box to the current PC name    
    #$WPFtextBox.Text = $env:COMPUTERNAME
#Adding code to a button, so that when clicked, it pings a system
# $WPFbutton.Add_Click({ Test-connection -count 1 -ComputerName $WPFtextBox.Text
# })
#===========================================================================
# Shows the form
#===========================================================================
write-host "To show the form, run the following" -ForegroundColor Cyan
'$Form.ShowDialog() | out-null'

要添加按钮单击处理程序,您可以像这样指定WPF外的操作:

[xml]$XAML = @"
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <Grid Margin="0,0,2,0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0*"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Label Name="Enter_Hostname_Label" Content="Enter Hostname:" HorizontalAlignment="Left" Height="26" Margin="9,19,0,0" VerticalAlignment="Top" Width="98" Grid.Column="1"/>
        <TextBox Name="Textbox" HorizontalAlignment="Left" Height="21" Margin="15,43,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="119" Grid.Column="1"/>
        <Label Name="Available_Hostnames_Label" Content="Available Hostnames:" HorizontalAlignment="Left" Height="26" Margin="11,83,0,0" VerticalAlignment="Top" Width="125" Grid.Column="1"/>
        <ListBox Name="Listbox" Grid.ColumnSpan="2" HorizontalAlignment="Left" Height="141" Margin="15,108,0,0" VerticalAlignment="Top" Width="119"/>
        <Button Name="Continue_Button" Grid.ColumnSpan="2" Content="Continue" HorizontalAlignment="Left" Height="21" Margin="143,108,0,0" VerticalAlignment="Top" Width="84" />
        <Button Name="Search_Button" Grid.ColumnSpan="2" Content="Search" HorizontalAlignment="Left" Height="21" Margin="143,43,0,0" VerticalAlignment="Top" Width="84" /> 
    </Grid>
</Window> 
"@ 
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
$Form=[Windows.Markup.XamlReader]::Load( (New-Object System.Xml.XmlNodeReader $XAML) )
$Form.FindName('Continue_Button').add_Click({
    param([System.Windows.Controls.Button]$sender, $e)
    Write-Host 'some action here'
})
$Form.ShowDialog()

最新更新