【问题标题】:Powershell. Accessing variable outside a Runspace instance电源外壳。访问运行空间实例之外的变量
【发布时间】:2021-07-27 20:08:13
【问题描述】:

我使用 WPF 和 Runspaces 编写了一个小型应用程序,但遇到了一些困难。

$Runspace = [runspacefactory]::CreateRunspace()
$Runspace.ApartmentState = "STA"
$Runspace.ThreadOptions = "ReuseThread"
$Runspace.Open()

$code = {
    #Build the GUI
    [xml]$xaml = @"
   $xaml_code
"@

    $syncHash = [hashtable]::Synchronized(@{ })
    $reader = (New-Object System.Xml.XmlNodeReader $xaml)
    $syncHash.Window = [Windows.Markup.XamlReader]::Load($reader)

    function RunspaceScript {
        param($syncHash, $Servers, $TargetBox)
            $syncHash.Host = $host
            $Runspace = [runspacefactory]::CreateRunspace()
            $Runspace.ApartmentState = "STA"
            $Runspace.ThreadOptions = "ReuseThread"
            $Runspace.Open()
            $Runspace.SessionStateProxy.SetVariable("syncHash", $syncHash)
            $Runspace.SessionStateProxy.SetVariable("Servers", $Servers)
            $Runspace.SessionStateProxy.SetVariable("TargetBox", $TargetBox)

            $code = {
                Function Add-OutputBoxLine {
                    Param ([string]$Message,[string]$Color = "Black")
                    $syncHash.Window.Dispatcher.invoke(
                            [action]{
                                $RichTextRange = New-Object System.Windows.Documents.TextRange($syncHash.$TargetBox.Document.ContentEnd, $syncHash.$TargetBox.Document.ContentEnd)
                                $RichTextRange.Text = "$Message`r`n"
                                $RichTextRange.ApplyPropertyValue([System.Windows.Documents.TextElement]::ForegroundProperty, "$Color")
                                $syncHash.$TargetBox.ScrollToCaret()
                            }
                    )
                }
                $syncHash.Window.Dispatcher.invoke(
                        [action]{ $syncHash.$TargetBox.Clear(); $syncHash.Start_Switchover.IsEnabled = $False })
                if (!$az_connection) {
                    $az_connection = Connect-AzAccount
                }
            }
            $PSinstance = [powershell]::Create().AddScript($Code)
            $PSinstance.Runspace = $Runspace
            $PSinstance.Runspace.Name = "SwitchOver"
            $job = $PSinstance.BeginInvoke()
    }

      # Click Actions
    $syncHash.Start_Switchover.Add_Click(
            {
                RunspaceScript -syncHash $syncHash -Servers $syncHash.Servers.Text -TargetBox "Process_Output"
            })

    $syncHash.Window.ShowDialog()
    $Runspace.Close()
    $Runspace.Dispose()
}

$PSinstance1 = [powershell]::Create().AddScript($Code)
$PSinstance1.Runspace = $Runspace
$job = $PSinstance1.BeginInvoke()

我想访问变量 $az_connection,该变量位于运行空间内,该运行空间位于函数“RunspaceScript”内,来自该函数的先前执行。 有什么想法可以实现吗?

附:这里的脚本代码因为规则我被强制删除了一些行,不要尝试复制运行代码,它不会起作用。

【问题讨论】:

    标签: wpf powershell runspace


    【解决方案1】:

    可能最简单的方法是将其添加到 $syncHash - $syncHash.AzConnection = $az_connection。否则,您需要将其作为脚本块的输出返回,然后在 AsyncResult 完成后提取输出。

    function RunspaceScript {
        param($syncHash, $Servers, $TargetBox)
        $syncHash.Host = $host
        $Runspace = [runspacefactory]::CreateRunspace()
        $Runspace.ApartmentState = 'STA'
        $Runspace.ThreadOptions = 'ReuseThread'
        $Runspace.Open()
        $Runspace.SessionStateProxy.SetVariable('syncHash', $syncHash)
        $Runspace.SessionStateProxy.SetVariable('Servers', $Servers)
        $Runspace.SessionStateProxy.SetVariable('TargetBox', $TargetBox)
    
        $code = {
            Function Add-OutputBoxLine {
                Param ([string]$Message, [string]$Color = 'Black')
                $syncHash.Window.Dispatcher.invoke(
                    [action] {
                        $RichTextRange = New-Object System.Windows.Documents.TextRange($syncHash.$TargetBox.Document.ContentEnd, $syncHash.$TargetBox.Document.ContentEnd)
                        $RichTextRange.Text = "$Message`r`n"
                        $RichTextRange.ApplyPropertyValue([System.Windows.Documents.TextElement]::ForegroundProperty, "$Color")
                        $syncHash.$TargetBox.ScrollToCaret()
                    }
                )
            }
            $syncHash.Window.Dispatcher.invoke(
                [action] { $syncHash.$TargetBox.Clear(); $syncHash.Start_Switchover.IsEnabled = $False })
            if (!$az_connection) {
                $az_connection = Connect-AzAccount
            }
    
            ## Output the connection from your scriptblock ##
            $az_connection
    
            ## OR just add it to your synchronized hashtable ##
            $syncHash.AzConnection = $az_connection
        }
        $PSinstance = [powershell]::Create().AddScript($Code)
        $PSinstance.Runspace = $Runspace
        $PSinstance.Runspace.Name = 'SwitchOver'
        $job = $PSinstance.BeginInvoke()
    
        ## Wait for the $code scriptblock to finish ##
        While (-not $job.IsCompleted) {
            Start-Sleep -Seconds 1
        }
    
        ## Pass the job to EndInvoke() to receive the output ##
        $az_connection = $PSinstance.EndInvoke($job) 
    
        ## Or access it from your synchronized hashtable ##
        $syncHash.AzConnection
    }
    

    【讨论】:

    • 我试过 $syncHash.AzConnection = $az_connection ,它就像一个魅力。感谢您的帮助;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 2011-05-11
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多