我正在尝试从C#代码调用PS脚本。
**PS code. -- Try.ps1**
Write-Host "HelloHost"
Write-Debug "HelloDebug"
Write-Output "HelloOutput"
echo "tofile" > $PSScriptRoot/a.txt
**C# code**
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management.Automation;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.Management.Automation.Runspaces;
namespace TryitOut
{
class Program
{
static void Main(string[] args)
{
using (PowerShell pshell = PowerShell.Create())
{
string path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
pshell.AddScript(path + "\\Try.ps1");
IAsyncResult result = pshell.BeginInvoke();
while (result.IsCompleted == false)
{
Console.WriteLine("Waiting for PS script to finish...");
Thread.Sleep(1000);
}
Console.WriteLine("Finished!");
Console.ReadKey();
}
}
}
}
当我独立运行“ Try.ps1”时,运行正常并创建a.txt,并按预期显示控制台输出。 但是,它不会通过此C#代码被调用/执行。 问题1 。您能帮我个忙吗? 问题2。通过C#代码调用Try.ps1时,如何查看PS控制台输出
谢谢您的时间:)。
答案 0 :(得分:1)
使用两种方法处理PowerShell对象的输出。一个是Invoke
调用的直接返回值,另一个是通过各种streams的返回值。在这两种情况下,您都有责任处理数据。当您在标准PowerShell窗口中运行脚本时,控制台不会自动输出它们。例如,要从Write-Object
获取结果,可以在C#
循环之后将以下内容添加到while
代码中:
foreach(PSObject pso in pshell.EndInvoke(result))
{
Console.WriteLine(pso);
}
这对于示例中的简单字符串很好,但是对于具有多个属性的复杂对象,您需要按名称提取单个属性。例如:
string propValue = pso.Members["PropertyName"].Value.ToString();
看看我以前的答案,看看将复杂对象转换为自己的类型的一种方法:Dealing with CimObjects with PowerShell Inside C#
像这样处理调试,信息,详细信息等
foreach(DebugRecord dbr in pshell.Streams.Debug)
{
Console.WriteLine(dbr);
}
您也需要将其添加到脚本的开头:
$DebugPreference = 'continue'