如何在没有WPF对象的情况下访问不同的Powershell运行空

如何在没有WPF对象的情况下访问不同的Powershell运行空

本文介绍了如何在没有WPF对象的情况下访问不同的Powershell运行空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在PowerShell运行空间上做了很多工作,我知道可以使用WPF对象中的调度程序在另一个运行空间中调用命令.

I worked quite a bit with PowerShell runspaces and I know it's possible to invoke commands in another runspace by using a dispatcher from WPF-objects.

我这样创建我的运行空间:

I create my runspaces like this:

$global:A = [hashtable]::Synchronized(@{})
$global:initialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
# Add some functions to the ISS
$GuiRunspace =[runspacefactory]::CreateRunspace($initialSessionState)
$GuiRunspace.ApartmentState = "STA"
$GuiRunspace.Open()
$GuiRunspace.SessionStateProxy.SetVariable("A",$A)
$GuiRunspace.SessionStateProxy.SetVariable("B",$B)
$GuiRunspace.Name = "GuiRunspace"

$Gui = [powershell]::Create()
[void]$Gui.addscript($GUILayerScript)
$Gui.Runspace = $GuiRunspace
$GuiThread = $Gui.beginInvoke()

使用以下代码,我可以从其他运行空间中操纵该运行空间:

And with the following code, I can manipulate that runspace from other runspaces:

$A.Window.Dispatcher.invoke({ *Do some crazy stuff that has nothing to do with the object from which you called the dispatcher* })

这仅有效,因为窗口是具有调度程序属性.

This only works because the window is a WPF-object that has the dispatcher property.

问题是,如何在没有WPF分发程序的情况下在其他运行空间 中调用命令?

The question is, how do I invoke a command in other runspaces without a WPF-dispatcher?

推荐答案

如果要在主执行上下文和单独的运行空间或运行空间池之间共享状态,请使用SessionStateProxy变量并分配同步的集合或字典:

If you want shared state between your main execution context and a separate runspace or runspace pool, use a SessionStateProxy variable and assign a synchronized collection or dictionary:

$sharedData = [hashtable]::Synchronized(@{})
$rs = [runspacefactory]::CreateRunspace()
$rs.Open()
$rs.SessionStateProxy.SetVariable('sharedData',$sharedData)

$sharedData变量现在在调用运行空间和内部$rs

The $sharedData variable now refers to the same synchronized hashtable in both the calling runspace and inside $rs

下面是如何使用运行空间的基本说明

您可以将运行空间附加到PowerShell对象的Runspace属性,它将在该运行空间中执行:

You can attach a runspace to the Runspace property of a PowerShell object and it'll execute in that runspace:

$rs = [runspacefactory]::CreateNewRunspace()
$rs.Open()
$ps = { Get-Random }.GetPowerShell()
$ps.Runspace = $rs
$result = $ps.Invoke()

您还可以将RunspacePool分配给多个PowerShell实例,并使其同时执行:

You can also assign a RunspacePool to multiple PowerShell instances and have them execute concurrently:

# Create a runspace pool
$rsPool = [runspacefactory]::CreateRunspacePool()
$rsPool.Open()

# Create and invoke bunch of "jobs"
$psInstances = 1..10 |ForEach-Object {
  $ps = {Get-Random}.GetPowerShell()
  $ps.RunspacePool = $rsPool
  [pscustomobject]@{
    ResultHandle = $ps.BeginInvoke()
    Instance = $ps
  }
}

# Do other stuff here

# Wait for the "jobs" to finish
do{
  Start-Sleep -MilliSeconds 100
} while(@($psInstances.ResultHandle.IsCompleted -eq $false).Count -gt 0)

# Time to collect our results
$results = $psInstances |ForEach-Object {
    if($_.Instance.HadErrors){
      # Inspect $_.Instance.Streams.Error in here
    }
    else {
      # Retrieve results
      $_.Instance.EndInvoke($_.ResultHandle)
    }
}

这篇关于如何在没有WPF对象的情况下访问不同的Powershell运行空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 12:21