Powershell WPF UI卡在循环中

时间:2018-01-24 16:28:26

标签: wpf powershell

我有以下脚本应该提示用户在两个字段中输入数据并将输入分配给变量。如果用户单击“确定”按钮而不输入数据,我希望再次弹出该表单。如果他们单击“取消”按钮,表单应该关闭。

当我将代码粘贴到PowerShell中时,它运行正常,但是当我在.ps1文件中运行它时,无论我做什么,UI都不会关闭。我尝试在正常和高级会话中运行.ps1。在我看来,$ userCancelled变量永远不会更改为$ true,我不知道为什么。有任何想法吗?感谢。

Function Start-PropertyGui {
[CmdletBinding()]

$inputXML = @"
<Window x:Class="WpfApplication1.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:WpfApplication1"
        mc:Ignorable="d"
        Title="UI" Height="227.396" Width="392.131">
    <Grid HorizontalAlignment="Left" Width="382">
        <TextBlock x:Name="textBlock" Margin="10,10,10,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="43"><Run FontWeight="Bold" Text="Click the Request button to request a new token or enter an existing token (ID and key) and click the OK button."/></TextBlock>
        <Button x:Name="requestButton" Content="Request API Token" HorizontalAlignment="Left" Margin="19,0,0,118" VerticalAlignment="Bottom"/>
        <Label x:Name="idLabel" Content="Access ID*" Margin="19,80,0,0" VerticalAlignment="Top"/>
        <TextBox x:Name="idTxt" Height="26" Margin="112,80,26,0" TextWrapping="Wrap" VerticalAlignment="Top" ToolTip=""/>
        <Label x:Name="keyLabel" Content="Access Key*" Margin="19,107,0,0" VerticalAlignment="Top"/>
        <TextBox x:Name="keyTxt" Height="26" Margin="112,107,26,0" TextWrapping="Wrap" VerticalAlignment="Top" ToolTip=""/>
        <Button x:Name="okButton" Content="OK" HorizontalAlignment="Left" Margin="19,0,0,19" VerticalAlignment="Bottom" Width="50" IsDefault="True"/>
        <Button x:Name="cancelButton" Content="Cancel" HorizontalAlignment="Left" Margin="80,0,0,19" VerticalAlignment="Bottom" Width="50"/>
    </Grid>
</Window>
"@

    $inputXML = $inputXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N' -replace '^<Win.*', '<Window'

    [void][System.Reflection.Assembly]::LoadWithPartialName('PresentationFramework')
    [xml]$XAML = $inputXML

    write-host ("{0}: Attempting to read the XAML data." -f (Get-Date -Format s))

    # Read XAML.
    $reader = (New-Object System.Xml.XmlNodeReader $xaml) 
    $form = [Windows.Markup.XamlReader]::Load($reader)

    # This line takes the XAML data, adds "WPF" to the front of each XML node name, and creates a global variable.
    $xaml.SelectNodes("//*[@Name]") | Foreach {Set-Variable -Name "WPF$($_.Name)" -Value $Form.FindName($_.Name) -Scope Global}

    # Specify what the 'request' button should do, when clicked.
    $WPFrequestButton.Add_Click({<#thisbuttonworks#>})

    # Specify what the OK button should do, when clicked.
    $WPFokButton.Add_Click({Set-Variable -Name AccessId -Value $WPFidtxt.Text -Scope Global; Set-Variable -Name AccessKey -Value $WPFkeytxt.text -Scope Global; $form.Close()})
    $WPFcancelButton.Add_Click({Set-Variable -Name userCancelled -Value $true -Scope Global -Force -ErrorAction Stop; $form.close()})

    #Now that the form is built, show it, surpressing other messages.
    write-host ("{0}: Starting UI." -f (Get-Date -Format s))

    $form.ShowDialog() | Out-Null
}

$AccessId = $null;$AccessKey = $null
$userCancelled = $false

Do {
    write-host ("{0}: Opening the UI." -f (Get-Date -Format s))

    Start-PropertyGui
} Until (
    (($userCancelled -eq $true) -or (($AccessId.length -eq 6) -and ($AccessKey.length -eq 10) -and ($userCancelled -eq $false)))
)
If ($userCancelled -eq $true) {
    write-host ("{0}: The user cancelled the collection of properties. To prevent errors, {1} will exit." -f (Get-Date -Format s), $MyInvocation.MyCommand)
}

write-host ("{0}: Using {1} and {2}." -f (Get-Date -Format s), $AccessId, $AccessKey)

1 个答案:

答案 0 :(得分:2)

看起来这是一个范围问题。由于您一次定义变量,然后再次定义为全局变量,因此需要将直接实例设置为使用全局范围的版本。

要解决此问题,请将$userCancelled$AccessId$AccessKey的所有引用更改为$global:userCancelled$global:AccessId$global:AccessKey