Объекты Powershell WFP, добавленные в SyncHash, не передаются в разные пространства выполнения

Я работаю над проектом, этот проект основан на WPF GUI Wizard. Основная идея инструмента заключается в том, что он попросит пользователя ввести некоторые данные и в то же время выполнить проверку предоставленных данных. Затем после того, как пользователь введет все необходимые данные на всех страницах мастера, инструмент вызовет индексы для выполнения своих функций. Что ж, WPF вызывает зависания и отсутствие ответа PowerShell, и чтобы преодолеть это, вам нужно использовать пробелы. Итак, что я делаю, так это то, что я открываю пространство выполнения, в котором будет работать графический интерфейс, а затем с помощью мастера, когда пользователь предоставляет ввод, я проверяю этот ввод в другом пространстве выполнения.

Моя проблема в том, что всякий раз, когда пользователь вводит данные, в пространстве выполнения графического интерфейса пользователя я вижу вводимые пользователем данные, но когда я вызываю другое пространство выполнения, я все еще вижу объект WPF, но ввод, предоставленный в этом объекте, недоступен.

Чтобы объяснить это дальше. Ниже приведен снимок экрана первого поля ввода в графическом интерфейсе. Например, я ввел что-то вроде (somqfqdn.anything), затем я нажимаю «Отправить». сам графический интерфейс работает в пространстве выполнения, называемом GuiRunspace, после нажатия кнопки отправки я создаю другое пространство выполнения, называемое MPSB1Runspace, и выполняю 2 проверки (ввод не пуст, предоставленное полное доменное имя разрешимо).

введите описание изображения здесь

Если я перешел в Runspace Debug, то в GuiRunspace, если я проверил текст поля ввода, я смогу увидеть ввод (somqfqdn.anything), но когда я перейду в MPSB1Runspace и проверю текст поля ввода, он окажется пустым.

Отладка Powershell Runspace выглядит следующим образом:

PS C:\Users\Administrator> Debug-Runspace Runspace32
Debugging Runspace: Runspace32
To end the debugging session type the 'Detach' command at the debugger prompt, or type 'Ctrl+C' otherwise.

Stopped at: $MPSB1Runspace = [runspacefactory]::CreateRunspace()
[DBG]: [Process:5900]: [Runspace32]: PS C:\Users\Administrator>> $GuiHash.WizardMainPageInputBox1.Text
somqfqdn.anything

[DBG]: [Process:5900]: [Runspace32]: PS C:\Users\Administrator>> 
Stopped at: $MPSB1PSSesion = [powershell]::Create()
[DBG]: [Process:5900]: [Runspace32]: PS C:\Users\Administrator>> 
Stopped at: $MPSB1PSSesion.runspace = $MPSB1Runspace
[DBG]: [Process:5900]: [Runspace32]: PS C:\Users\Administrator>> 
Stopped at: $MPSB1Runspace.Open()
[DBG]: [Process:5900]: [Runspace32]: PS C:\Users\Administrator>> 
Stopped at: $MPSB1Runspace.SessionStateProxy.SetVariable("GuiHash",$Global:GuiHash)
[DBG]: [Process:5900]: [Runspace32]: PS C:\Users\Administrator>> 
Stopped at: [void]$MPSB1PSSesion.AddScript({
[DBG]: [Process:5900]: [Runspace32]: PS C:\Users\Administrator>> 
Stopped at: })
[DBG]: [Process:5900]: [Runspace32]: PS C:\Users\Administrator>> 

PS C:\Users\Administrator> Debug-Runspace Runspace34
Debugging Runspace: Runspace34
To end the debugging session type the 'Detach' command at the debugger prompt, or type 'Ctrl+C' otherwise.

Stopped at: If ($GuiHash.WizardMainPageInputBox1.Text.Length -Eq 0) {
[DBG]: [Process:5900]: [Runspace34]: PS C:\Users\Administrator>> $GuiHash.WizardMainPageInputBox1.Text

[DBG]: [Process:5900]: [Runspace34]: PS C:\Users\Administrator>> $Global:GuiHash.WizardMainPageInputBox1.Text

Кроме того, я добавил строку кода в MPSB1Runspace, чтобы отключить другую кнопку отправки, но это действие не выполняется, что означает, что MPSB1Runspace не имеет доступа к SyncHash, однако я добавил SyncHash в MPSB1Runspace с помощью SessionStateProxy .SetVariable.

Мой код выглядит следующим образом:

#   Create an Array that will hold all the XAML pages variables.
$XamlFilesArray = @($WizardMainWindowXaml, $WizardMainPageXaml, $WizardVCPageXaml, $WizardHostingVCPageXaml, $WizardControllerPageXaml, $WizardPrimaryNsxPageXaml, $WizardPrimaryVCPageXaml, $WizardFinalPageXaml)
#   Create  Sync HashTable (GuiHash) to allow readability across different Runscpases and add required variables.
$Global:GuiHash = [hashtable]::Synchronized(@{ })
#   Crate the Runspace that will be used for the GUI
$GuiRunspace =[runspacefactory]::CreateRunspace()
$GuiRunspace.ApartmentState = "STA"
$GuiRunspace.ThreadOptions = "ReuseThread"         
$GuiRunspace.Open()
$GuiRunspace.SessionStateProxy.SetVariable("GuiHash",$Global:GuiHash) 
#   Create a PowerShell Session and add it to the Runspace.
$GuiPSSession = [PowerShell]::Create()
$GuiPSSession.Runspace = $GuiRunspace
#   Create the GUI PowerShell Session ScriptBlock.
[void]$GuiPSSession.AddScript({

    ####Some the rest of the code that will build the GUI and load XAML Files

    #   Configure WizardMainPageSubmitButton1
    $GuiHash.WizardMainPageSubmitButton1.Add_Click({
        # Create new Runspace for this task. 
        $MPSB1Runspace = [runspacefactory]::CreateRunspace()
        $MPSB1PSSesion = [powershell]::Create()
        $MPSB1PSSesion.runspace = $MPSB1Runspace
        $MPSB1Runspace.Open()
        $MPSB1Runspace.SessionStateProxy.SetVariable("GuiHash",$Global:GuiHash)
        [void]$MPSB1PSSesion.AddScript({
            If ($GuiHash.WizardMainPageInputBox1.Text.Length -Eq 0) {
                $GuiHash.WizardMainPageErrorMessage.Dispatcher.Invoke([action]{$GuiHash.WizardMainPageErrorMessage.Foreground= "Red"})  #   Make Sure Printing Color is Red.
                $GuiHash.WizardMainPageErrorMessage.Dispatcher.Invoke([action]{$GuiHash.WizardMainPageErrorMessage.Text = "Provided Data is empty, please provide NSX FQDN."})  #   Print Error
            }   Else {
                    # Check if the input FQDN from WizardMainPageInputBox1 is resolvable and if not print error
                    If (!(Resolve-DnsName -Name $GuiHash.WizardMainPageInputBox1.Text.Text -ErrorAction SilentlyContinue)) {
                        $GuiHash.WizardMainPageErrorMessage.Dispatcher.Invoke([action]{$GuiHash.WizardMainPageErrorMessage.Foreground= "Red"})  #   Make Sure Printing Color is Red.
                        $GuiHash.WizardMainPageErrorMessage.Dispatcher.Invoke([action]{$GuiHash.WizardMainPageErrorMessage.Text = "Provided NSX FQDN is not resolvable. Please try again."})    #   Print Error                  
                    }   Else {
                            # Print Success, enable WizardMainPageInputBox2
                            $GuiHash.WizardMainPageErrorMessage.Dispatcher.Invoke([action]{$GuiHash.WizardMainPageErrorMessage.Foreground= "White"})        #   Make Sure Printing Color is White.
                            $GuiHash.WizardMainPageErrorMessage.Dispatcher.Invoke([action]{$GuiHash.WizardMainPageErrorMessage.Text = "Provided NSX FQDN confirmed. Please provide credentials."})  #   Print Message
                            $GuiHash.WizardMainPageInputBox2.Dispatcher.Invoke([action]{$GuiHash.WizardMainPageInputBox2.IsEnabled= "True"})    #   Enable WizardMainPageInputBox2 to continue

                        }
                }   
        }).BeginInvoke()   

    }).BeginInvoke()  

    #   Show Wizard Window.
    $Global:GuiHash.WizardMainWindow.ShowDialog() | Out-Null

}).BeginInvoke()    

$ShowGui = $GuiPSSession.BeginInvoke()

С приведенным выше кодом и вводом somefqdn.anything я должен увидеть сообщение об ошибке, в котором указано, что полное доменное имя NSX не разрешается. Пожалуйста, попробуйте еще раз.

Спасибо за помощь.


person Taher Shaker    schedule 19.05.2019    source источник


Ответы (1)


После некоторых тестов мне удалось обойти эту проблему. когда я вызываю второе пространство выполнения, я передал содержимое текстового поля в другую переменную и добавил его во вторую переменную набора повторной распаковки

Код, как показано ниже:

                $MPSB1Runspace = [runspacefactory]::CreateRunspace()
                $MPSB1PSSesion = [powershell]::Create()
                $MPSB1PSSesion.runspace = $MPSB1Runspace
                $MPSB1Runspace.Open()
                $MPSB1Runspace.SessionStateProxy.SetVariable("GuiHash",$Global:GuiHash)
                $MPSB1Runspace.SessionStateProxy.SetVariable("NsxFqdn",$Global:GuiHash.WizardMainPageInputBox1.Text)
                [void]$MPSB1PSSesion.AddScript({
                       your code goes here and now $NsxFqdn have the input value
                })
person Taher Shaker    schedule 20.05.2019