如何在C#中解析powerShell控制台的输出?
PowerShell控制台输出:
Name : 0F06B9DF-9FC5-4AF7-AF92-890AAD415000
ElementName : Virtual Machine 1
Name : 2B501DD8-46F5-45FE-ACCE-62030720A000
ElementName : Virtual Machine 2
在我的C#代码中逐行读取输出。我搜索将输出转换为的最佳方法
List<Dictionary<string, string>>
我试过了
bool dataset = false;
Dictionary<string, string> data = new Dictionary<string, string>();
proc.Start();
while (!proc.StandardOutput.EndOfStream)
{
// The line of Output
string line = proc.StandardOutput.ReadLine();
// If line is not empty save data in dictionary
if(line.Length != 0)
{
dataset = true;
string[] vals = line.Split(':');
data.Add(vals[0], vals[1]);
}
// Else, save dictionary in list and reinit dictionary
else
{
// Next object
if (dataset)
{
arr.Add(data);
dataset = false;
data = new Dictionary<string, string>();
}
}
}
如果进程快速完成并且没有提供大量输出,那么等待它退出然后立即读取所有标准输出流可能是个好主意。
proc.WaitForExit((int)TimeSpan.FromSeconds(10).TotalMilliseconds);
var ret = new List<Dictionary<string, string>>();
// first split on double newline to separate VMs
string[] vms = proc.StandardOutput.ReadToEnd()
.Split(new[] { string.Format("{0}{0}", Environment.NewLine) }, StringSplitOptions.RemoveEmptyEntries);
foreach (var vm in vms)
{
// then split on newline, to get each line in separate string
var lines = vm.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
// finally, split each line on ':' to fill in dictionary, then add it to list
ret.Add(lines.Select(line => line.Split(':')).ToDictionary(a => a[0].Trim(), a => a[1].Trim()));
}
如果进程输出不是您期望的格式,您可能还希望将其包装在try...catch
中。
来吧! C#和Powershell - 两种.Net语言。您可以从C#调用Powershell脚本并将输出作为对象。无需解析任何东西:
static void Main(string[] args)
{
var rsc = RunspaceConfiguration.Create();
var runSpace = RunspaceFactory.CreateRunspace(rsc);
runSpace.Open();
Runspace.DefaultRunspace = runSpace;
var p = runSpace.CreatePipeline("Get-Process");
var output = p.Invoke();
foreach (var o in output)
{
Console.WriteLine("{0}", o.Properties["Name"].Value);
}
}
using (PowerShell PowerShellInstance = PowerShell.Create())
{
// this script has a sleep in it to simulate a long running script
PowerShellInstance.AddScript("GET-VM");
//PowerShellInstance.AddCommand("Out-String");
// begin invoke execution on the pipeline
foreach (var o in PowerShellInstance.Invoke())
{
//Console.WriteLine(str);
Console.WriteLine("{0}", o.Properties["Name"].Value);
Console.WriteLine("{0}", o.Properties["Status"].Value);
}
// do something else until execution has completed.
// this could be sleep/wait, or perhaps some other work
}