英文:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论