【发布时间】:2020-01-22 21:30:34
【问题描述】:
TLDW:为了支持特定进程,我需要从一个 powershell 实例/模块启动一个已知的安全可执行文件以用于某些 c# 魔法,然后需要在退出之前启动并执行一个 powershell 脚本。
Powershell 入口点 { 已知的好exe { Powershell 工作要做 } }
现在理想情况下,这将全部从单个控制台实例运行,以便所有输出都易于查看。使用 powershell.Streams 时,exe -> powershell 日志记录一切正常,符合预期。powershell 中的写入主机都显示在控制台中,我得到了我想要的所有信息。
powerShell.Streams.Information.DataAdded += LogMessage;
引入外部powershell模块时出现问题。这个是必需的,因为它运行的父进程和执行环境是 powershell。一旦从 powershell 实例中启动整个堆栈,我就会从外部 powershell 和 exe 获得控制台日志记录。但是内部 powershell 模块中的所有写入主机都消失了。
我已尝试禁用流重定向以及其他一些操作,但这并没有以我希望的方式解决。我希望有人知道是否有办法让它工作,因为它可以解决很多问题。
PowerShell 外部:
$C#Exe = Join-Path $PSScriptRoot $C#ExePath
$C#Args = @()
Write-Host "Hello world" # will show up
& $C#Exe $C#Args
C# 执行代码:
public static void Main(string[] args)
{
Console.WriteLine("Hello world"); #Will show up
var powerShell = PowerShell.Create().AddScript("PowerShellInner.ps1");
powerShell.Streams.Information.DataAdded += LogMessage<InformationRecord>;
powerShell.Streams.Warning.DataAdded += LogMessage<WarningRecord>;
powerShell.Streams.Error.DataAdded += LogMessage<ErrorRecord>;
powerShell.Streams.Verbose.DataAdded += LogMessage<VerboseRecord>;
powerShell.Streams.Debug.DataAdded += LogMessage<DebugRecord>;
StringBuilder resultString = new StringBuilder();
foreach (dynamic item in powerShell.Invoke().ToList())
{
resultString.AppendLine(item.ToString());
}
Console.WriteLine(resultString.ToString());
}
private static void LogMessage<T>(object sender, DataAddedEventArgs e)
{
var data = (sender as PSDataCollection<T>)[e.Index];
Console.WriteLine($"[{typeof(T).Name}] {Convert.ToString(data)}");
}
PowerShell 内部:
Write-Host "Hello world" #Wont show up
【问题讨论】:
-
不,也许要澄清一下,我真正的问题是为什么使用外部 powershell 运行它会导致 c# ps 流重定向失败?
-
那么,您有一个调用 exe(用 C# 编写)的 powershell 脚本,而 C# 程序又在执行一个 powershell 脚本?我很困惑,因为当你说“Powershell”时,我不确定你是指正在执行 exe 的 PS,还是指正在执行 exe 的 PS
-
@Nova 您在调用堆栈的摘要中完全正确。
-
那么,您在问题中显示的 PS 是“外部”PS,是吗?
标签: c# powershell logging