Объекты Powershell WFP, добавленные в SyncHash, не передаются в разные пространства выполнения - PullRequest
0 голосов
/ 20 мая 2019

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

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

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

enter image description here

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

Отладка 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 не разрешаемо». Пожалуйста, попробуйте еще раз.

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

1 Ответ

0 голосов
/ 20 мая 2019

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

Код как ниже:

                $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
                })
...