【问题标题】:How to access underlying pipeline in Powershell Api C#如何在 Powershell Api C# 中访问底层管道
【发布时间】:2018-07-19 19:27:14
【问题描述】:

我需要访问由于Pwoershell.Create(); 而创建的底层 powershell 默认管道我需要停止该管道,以便必须立即停止脚本执行。

我知道我可以通过调用 pipeline.Invoke() 创建 Pipeline 对象并执行脚本。但是 Pipeline 对象没有给我 Powershell 实例提供的所有数据流。

powerShellInstance = PowerShell.Create();
powerShellInstance.Runspace = RunspaceFactory.CreateRunspace(iss)

稍后我需要一点

powerShellInstance.GetPipeline().Stop()  // something like this.

我有什么办法可以做到这一点吗?

编辑

例如我有以下脚本。

Set-LinkParameter"withError"  => This commandlet will throw error
Set-LinkParameter11 "Mistyped" "error" => Powershell will throw an error of invalid commandlet

Initialiize-Access  => this is invalid here and this commandlet will throw error.  Here it must not allow further script to execute.

Write-Host "This is test message for host"
Write-Information "test information"

Write-Error "Access denied."  --> this is can be terminating error ( depends)
Write-Warning "This is test warning." 
Write-Verbose "This is verbose message"
Write-Verbose "This is verbose message" -Verbose

Write-Debug "Test Debug message" -Debug
Write-Debug "wont appear at debug pipeline"

Write-Output @(1,2,3) -NoEnumerate | measure

编辑(异步停止) 在代码之前..

powerShellInstance.Streams.Error.DataAdded += OnError

OnError(sender,event)
{
   //this would have been invoked asyncronously. 
   powerShellInstance.BeginStop(null,null);
}

【问题讨论】:

  • PowerShell 类也有一个Stop 方法,你试过吗?
  • 我在错误处理程序中使用了该处理程序,该处理程序被订阅以记录错误并从那里终止。但它以某种方式挂起整个 powershell 执行并且不会返回。
  • 我认为,在 Stop 调用时,它应该终止当前正在执行的管道并关闭运行空间。
  • 如果在调用Stop 时当前正在运行的命令是阻塞的并且没有实现StopProcessing 则无法取消该命令。这在直接在 PowerShell 中调用方法时最常见,但某些编译的命令也可能无法停止。除了终止进程之外,没有办法保证管道的取消。
  • 那么当我发现第一个错误时停止执行 powershell 脚本的理想方法应该是什么。我使用了 BeginStop,它似乎有效。因为,它使用 IAsyncResult 和 state 调用异步方法。

标签: c# powershell pipeline runspace


【解决方案1】:

很遗憾,您不能直接回答您原来的问题。没有公开可访问的方式来获取当前运行的管道,无论是通过PowerShell 类还是其他方式。与Pipeline 交互的唯一方法是通过Runspace.CreatePipeline 创建它。此外,Pipeline API is not available in PowerShell Standard 最终将被删除。

您修改后的问题“如何在出错后终止通过 PowerShell 类调用的 PowerShell 脚本”(转述)的答案是使用 PowerShell.Stop()

但是,正如您所注意到的,这并不能保证终止。原因是当您的事件触发并调用PowerShell.Stop() 时,PowerShell 脚本可能已经移动到下一个序列点。如果下一个序列点是阻塞的方法调用,或者是未实现 Cmdlet.StopProcessing 的 cmdlet,则管道将在完成之前停止。如果它永远不会完成,那么PowerShell.Stop 永远不会完成。除了终止进程之外,没有其他办法。

【讨论】:

  • 以异步方式停止怎么样。我尝试过并且似乎正在工作。我需要 sugetions 是否是一种安全的方法?
猜你喜欢
  • 2021-03-03
  • 2012-05-10
  • 2017-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多