[英]Passing an associative array from c# to Powershell
我想将一个关联数组从 C# 传递给 Powershell。 作为一个例子,我想执行这个 powershell 代码行:
PS C:\> get-command | select name, @{N="Foo";E={"Bar"}} -first 3
Name Foo
---- ---
Add-Content Bar
Add-History Bar
Add-Member Bar
我想通过不同命令的管道而不是标记为脚本的单个命令来做到这一点。 这是代码:
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.Add("get-command");
Command c = new Command("select-object");
List properties = new List();
properties.Add("name");
properties.Add("@{N=\"Foo\";E={\"Bar\"}}");
c.Parameters.Add("Property", properties.ToArray());
c.Parameters.Add("First", 3);
pipeline.Commands.Add(c);
pipeline.Commands.Add("Out-String");
Collection retval = pipeline.Invoke();
runspace.Close();
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in retval)
Console.WriteLine(obj.ToString());
但是作为参数传递给 Select-Object 的关联数组没有被正确解析。 这是另一面的结果:
PS C:\test> c:\test\Bin\Debug\test.exe
Name @{N="Foo";E={"Bar"}}
---- --------------------
Add-Content
Add-History
Add-Member
我如何设置 Select-Object 命令参数有什么问题?
通过 c# 创建管道和使用本机 powershell 脚本创建管道有一个实际上非常微妙的主要区别:参数绑定器。
如果我用纯脚本编写你的代码版本,我会得到同样的错误:哈希表文字被视为字符串值。
ps> $ps = $ps.Commands.Add("get-process")
ps> $ps = $ps.Commands.Add("select-object")
ps> $ps.Commands[1].Parameters.Add("Property", @("Name", '@{N="Foo";E={"Bar"}}'))
在这种情况下,该命令接收一个由两个字符串组成的数组,即“名称”和哈希表文字字符串。 这将以与您的 C# 完全相同的方式被破坏。 现在,看看正确的方法(在脚本中)——让我重写第 3 行:
ps> $ps.Commands[1].Parameters.Add("Property", @("Name", @{N="Foo";E={"Bar"}}))
那么发生了什么变化? 我删除了散列表周围的引号——我将散列表作为 object 数组的第二个元素传递,因此,为了让您的 C# 示例正常工作。 您需要在命令行中执行参数绑定器为我们执行的操作(这非常多:)。 代替:
properties.Add("@{N=\"Foo\";E={\"Bar\"}}");
和
properties.Add(
new Hashtable {
{"N", "Foo"},
{"E", System.Mananagement.Automation.ScriptBlock.Create("\"Foo\"")}
}
);
我希望这可以为您解决问题。 参数绑定器可能是 powershell 体验中最不显眼但最强大的部分。
-Oisin
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.