Capture powershell output from C#

huangapple go评论81阅读模式
英文:

Capture powershell output from C#

问题

我正在尝试运行这段C#代码:

Runspace rs = RunspaceFactory.CreateRunspace();
rs.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = rs;
ps.AddScript("Write-Output Hello | Out-File -FilePath myfile.txt");
ps.Invoke();

myfile.txt 应该包含 Hello,但文件不存在。如何重定向PowerShell命令的标准输出(和错误消息)?

谢谢

编辑

我已经理解了问题:Invoke命令不是阻塞命令。因此,当Invoke()完成时,myfile.txt文件尚不存在。

有没有等待PowerShell脚本结束的方法?谢谢

英文:

I am trying to run this C# code:

Runspace rs = RunspaceFactory.CreateRunspace();
rs.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = rs;
ps.AddScript("Write-Output Hello | Out-File -FilePath myfile.txt");
ps.Invoke();

myfile.txt should contain Hello but the file does not exist. How can i redirect powershell commands standard output (and errors) ?

Thanks

*** EDIT ***

I have understood the problem: The Invoke command is not a blocking-command. So when Invoke() has finished, my file.txt does not exist yet.

Is there a way to wait for powershelgl script ending ? Thanks

答案1

得分: 1

I have understood the problem: The Invoke command is not a blocking-command. So when Invoke() has finished, my file.txt does not exist yet.

你误解了问题,Invoke() 是一个同步方法。

You haven't specified a location in which to operate (eg. cd C:\some\path\ in the PowerShell script), so PowerShell will use the working directory of the hosting process as its default location. The file will be written to the directory from which you launched your application, or the root of your user profile if you launched the application from the shell in Windows.

你没有指定要操作的位置(例如,在PowerShell脚本中使用cd C:\some\path\),因此PowerShell将使用托管进程的工作目录作为默认位置。该文件将被写入启动应用程序的目录,或者如果你从Windows的shell中启动应用程序,则会写入用户配置文件的根目录。

If you want to consume the output in your C# application, iterate over the return value from Invoke() instead:

如果你想在你的C#应用程序中使用输出,那么应该迭代Invoke()的返回值:

Runspace rs = RunspaceFactory.CreateRunspace();
rs.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = rs;
ps.AddScript("Write-Output Hello");

foreach (var outputItem in ps.Invoke()) {
  if (ps.HadErrors) {
    Console.WriteLine("Errors encountered!");
    foreach (var errorRecord in ps.Streams.Error) {
      Console.WriteLine(errorRecord);
      Console.WriteLine(errorRecord.ScriptStackTrace);
    }
    break;
  }
  Console.WriteLine(outputItem.BaseObject); // this will print the string Hello
}
英文:

> I have understood the problem: The Invoke command is not a blocking-command. So when Invoke() has finished, my file.txt does not exist yet.

You've misunderstood the problem, Invoke() is a synchronous method.

You haven't specified a location in which to operate (eg. cd C:\some\path\ in the PowerShell script), so PowerShell will use the working directory of the hosting process as it's default location. The file will be written to the directory from which you launched your application, or the root of your user profile if you launched the application from the shell in Windows.


If you want to consume the output in your C# application, iterate over the return value from Invoke() instead:

Runspace rs = RunspaceFactory.CreateRunspace();
rs.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = rs;
ps.AddScript("Write-Output Hello");

foreach (var outputItem in ps.Invoke()) {
  if (ps.HadErrors) {
    Console.WriteLine("Errors encountered!")
    foreach (var errorRecord in ps.Streams.Error) {
      Console.WriteLine(errorRecord);
      Console.WriteLine(errorRecord.ScriptStackTrace);
    }
    break;
  }
  Console.WriteLine(outputItem.BaseObject); // this will print the string Hello
}

huangapple
  • 本文由 发表于 2023年5月10日 14:22:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76215413.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定