簡體   English   中英

從不同的運行空間調用scriptblock

[英]Calling scriptblock from different runspace

我正在開發一個創建GUI向導工具的項目,這個GUI向導工具首先從用戶獲取一些數據並同時執行驗證(例如連接,DNS解析,API連接等)。 GUI向導工具從用戶獲取所有必需的數據后,它將開始調用其他下標。

為了使GUI向導更快並克服這種無響應問題,我使用的是Runspaces,GUI本身將在Runspace中運行,任何其他任務(如執行驗證檢查)也將在不同的Runspace中運行。

為了簡化我的代碼並使其更容易和更有條理,我使用腳本塊。 我在GUI Runspace中創建了許多腳本塊,只要點擊GUI中的提交按鈕就可以使用它。 對於每個提交按鈕,將有一個不同的腳本塊,並且一些提交按鈕將執行相同的腳本塊。

我的問題是調用腳本塊。 每當我在Add_Click操作中添加腳本塊時,腳本塊都不會被執行,我嘗試在腳本塊中使用Wait-Debugger,我甚至看不到InBreakpoint狀態下的任何運行空間。

如果我在PowerShell中遇到runpaces和WPF,那么請問我是否做錯了。 謝謝您的幫助。

#   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(@{ })
$Global:GuiHash.IPCehckPattern = $IPCehckPattern #  Add the IPCehckPattern Variable to be used within other runspaces

#   Crate the Runspace that will be used for the GUI and configure settings. After, Open the Runspace and import variables.
#   You must import variables that will be used in other Runspaces, thus importing the required variables to this Runspace.
$GuiRunspace =[runspacefactory]::CreateRunspace()
$GuiRunspace.ApartmentState = "STA"
$GuiRunspace.ThreadOptions = "ReuseThread"         
$GuiRunspace.Open()
$GuiRunspace.SessionStateProxy.SetVariable("GuiHash",$Global:GuiHash)  
$GuiRunspace.SessionStateProxy.SetVariable("XamlFilesArray",$XamlFilesArray)

#   Create a PowerShell Session and add it to the Runspace.
$GuiPSSession = [PowerShell]::Create()
$GuiPSSession.Runspace = $GuiRunspace

#   Create the GUI PowerShell Session ScriptBlock. This will be the main code of the tool.
[void]$GuiPSSession.AddScript({
    $ScriptBlockMainPageSubmitButton1 = {

        #   This Script block will be called when the first Submit Button in the Main page is clicked.
        #   This will handle the NSX Manager FQDN and perform the required checks
        #   Actions this Script Block will perform are as follow:
        #       1- Check if the input value is empty, if so print error.
        #       2- Check if the Provided FQDN is resolvable.
        #       3- Check if the provided FQDN is reachable on port 443.

        Param($GuiHash)

        Process {
            # Check if WizardMainPageInputBox2 is enabled and if so then disable it.
            If ($GuiHash.WizardMainPageInputBox2.IsEnabled -Eq "False") {$GuiHash.WizardMainPageInputBox2.Dispatcher.Invoke([action]{$GuiHash.WizardMainPageInputBox2.IsEnabled= "True"})}

            # Check if the input data is empty and if so Write Error
            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
                $GuiHash.WizardMainPageInputBox1.Dispatcher.Invoke([action]{$GuiHash.WizardMainPageInputBox1.Text = "NSX Manager FQDN:"})   #   Revert Text in InputBox to default.
            }   Else {
                    # Check if the input FQDN from WizardMainPageInputBox1 is resolvable and if not print error
                    If (!(Resolve-DnsName -Name $GuiHash.WizardMainPageInputBox1.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
                        $GuiHash.WizardMainPageInputBox1.Dispatcher.Invoke([action]{$GuiHash.WizardMainPageInputBox1.Text = "NSX Manager FQDN:"})   #   Revert Text in InputBox to default.
                    }   Else {
                            # Check Reachability of provided FQDN using port 443.
                            # Print Activity Message.
                            $GuiHash.WizardMainPageErrorMessage.Dispatcher.Invoke([action]{$GuiHash.WizardMainPageErrorMessage.Foreground= "Green"})    #   Make Sure Printing Color is Green.
                            $GuiHash.WizardMainPageErrorMessage.Dispatcher.Invoke([action]{$GuiHash.WizardMainPageErrorMessage.Text = "Please wait while checking reachability."})  #   Print Message

                            If (!((Test-NetConnection $NsxManagerFQDN -Port 443 -WarningAction SilentlyContinue).TcpTestSucceeded)) {
                                # Print Error and reset the Inputbox text to default.
                                $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 reachable over port 443. Please try again."})       #   Print Error
                                $GuiHash.WizardMainPageInputBox1.Dispatcher.Invoke([action]{$GuiHash.WizardMainPageInputBox1.Text = "NSX Manager FQDN:"})       #   Revert Text in InputBox to default.
                            }   Else {
                                    # Print Success, enable WizardMainPageInputBox2, Disable WizardMainPageSubmitButton1 and add NSX FQDN to Sync Hash
                                    $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
                                    $GuiHash.WizardMainPageSubmitButton1.Dispatcher.Invoke([action]{$GuiHash.WizardMainPageSubmitButton1.IsEnabled= "False"})   #   Disable WizardMainPageSubmitButton1
                                    $GuiHash.NsxManagerFQDN = $GuiHash.WizardMainPageInputBox1.Text     #   Add provided NSX FQDN to GuiHash
                                }
                        }
                }
        }
    }
    #   Run a ForEach Loop to Read each Xaml Page, load the page and lastly add each node within the Xaml to the (GuiHash).
    ForEach ($File in $XamlFilesArray) {
        $TempReadXamlFile=(New-Object System.Xml.XmlNodeReader $File)   #   Read Xaml Page
        $TempWindowForm=[Windows.Markup.XamlReader]::Load($TempReadXamlFile)    #   Load the Wizard XAML Files in a GUI Form
        $File.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | ForEach-Object {$Global:GuiHash.Add($_.Name, $TempWindowForm.FindName($_.Name))}    #   Add all XAML Nodes to the HashTable
    }

    #   Set the First page on the Wizard Window to be the WizardMainPageGrid.


$Global:GuiHash.WizardFram.NavigationService.Navigate($Global:GuiHash.WizardMainPageGrid) | Out-Null
$Global: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({$ScriptBlockMainPageSubmitButton1}).AddArgument($Global:GuiHash)
                $ExecScriptObject = $MPSB1PSSesion.BeginInvoke()
            })
#   Show Wizard Window.
        $Global:GuiHash.WizardMainWindow.ShowDialog() | Out-Null

    })  

    $ShowGui = $GuiPSSession.BeginInvoke()

我的期望是,當我點擊輸入框並提供不正確的FQDN時,GUI會出現問題而出錯。

在進行了幾次測試和檢查之后,事實證明問題非常簡單,這完全是我的錯。 當我調用我正在使用的AddScript({})時,你應該只使用()。 所以刪除{}並使它只有()后,它工作正常。 舉個例子,

            $Global: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($ScriptBlockMainPageSubmitButton1).AddArgument($Global:GuiHash)
                $ExecScriptObject = $MPSB1PSSesion.BeginInvoke()
            })

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM