从C#代码调用PS脚本(Visual Studio 2017)

时间:2018-08-08 08:13:22

标签: c# .net powershell

我正在尝试从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控制台输出

谢谢您的时间:)。

1 个答案:

答案 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'