我正在尝试在Powershell中使用VisualStudio创建的GUI。
因此,我必须将Visual Studio中的XAML代码导入到脚本中
这是我到目前为止所得到的:
[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”。错误:“名称不允许以符号'<'开头,十六进制值为0x3C
但是我无法更改此设置,因为如果这样做,GUI代码将无法工作
我在互联网上进行了很多搜索,但找不到解决方案。似乎对每个这样的人都有效
有人可以告诉我我的脚本出了什么问题吗?
答案 0 :(得分:0)
要添加按钮单击处理程序,可以在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()
答案 1 :(得分:0)
有关如何使用Visual Studio创建PowerShell GUI的完整系列。
使用Visual Studio在几分钟内创建PowerShell GUI –一个新希望
https://foxdeploy.com/2015/04/16/part-ii-deploying-powershell-guis-in-minutes-using-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:\Users\Stephen\Dropbox\Docs\blog\foxdeploy 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'