简体   繁体   English

电源外壳。 在 Runspace 实例之外访问变量

[英]Powershell. Accessing variable outside a Runspace instance

I wrote a small application using WPF and Runspaces and ran into some difficulties.我使用 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()

I want to access variable $az_connection which is inside a runspace which is inside a function "RunspaceScript" from previous execution of that function.我想访问变量 $az_connection ,它位于运行空间内,该运行空间位于先前执行该函数的函数“RunspaceScript”内。 Any ideas how it can be achieved?任何想法如何实现?

PS I was forced to remove some lines from the script code here because of the rules, don't try to copy and run the code, it will not work. PS我这里因为规则被迫从脚本代码中删除了一些行,不要试图复制和运行代码,它不会工作。

Probably the easiest way is to add it to $syncHash - $syncHash.AzConnection = $az_connection .可能最简单的方法是将它添加到 $syncHash - $syncHash.AzConnection = $az_connection Otherwise you need to return it as output from your scriptblock and then pull the output once the AsyncResult completes.否则,您需要将其作为脚本块的输出返回,然后在 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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM