将关联数组从 C# 传递到 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 命令参数的方式有什么问题?
I'd like to pass an associative array from C# to Powershell. As an example I'd like to execute this powershell line of code:
PS C:\> get-command | select name, @{N="Foo";E={"Bar"}} -first 3
Name Foo
---- ---
Add-Content Bar
Add-History Bar
Add-Member Bar
I'd like to do this via a Pipeline of distinct Commands as opposed to a single command marked as a script. Here's the code:
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());
But that associative array being passed in as a parameter to Select-Object isn't being parsed correctly. This is what comes out the other side:
PS C:\test> c:\test\Bin\Debug\test.exe
Name @{N="Foo";E={"Bar"}}
---- --------------------
Add-Content
Add-History
Add-Member
What's wrong with how I'm setting up the Select-Object command parameters?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
通过 C# 创建管道和使用本机 powershell 脚本创建管道有一个主要区别,实际上非常微妙:参数绑定器。
如果我用纯脚本编写代码的一个版本,我会得到相同的错误:哈希表文字被视为字符串值。
在本例中,该命令接收一个由两个字符串组成的数组,即“名称”和哈希表文字字符串。 这将以与 C# 完全相同的方式被破坏。 现在,看一下正确的方法(在脚本中)——让我重写第 3 行:
那么发生了什么变化? 我删除了哈希表周围的引号——我将哈希表作为对象数组的第二个元素传递! 因此,为了让您的 C# 示例正常工作,您需要执行参数绑定器在命令行中为我们所做的工作(这相当多!)。 :
替换
我希望这可以帮助您解决问题。 参数绑定器可能是 powershell 体验中最不可见但最强大的部分。
-奥辛
Creating a pipeline through c# and creating a pipeline with native powershell script have one major difference that is actually quite subtle: the parameter binder.
if I write a version of your code in pure script, I will get the same error: the hashtable literal is treated as a string value.
In this case, the command receives an array of two strings, the "name" and the hashtable literal string. This will be broken in exactly the same way as your C#. Now, take a look at the right way to do it (in script) - let me rewrite line 3:
So what changed? I removed the quotes around the hashtable -- I am passing a hashtable as the 2nd element of the object array! So, to get your C# example to work, you need to do what the parameter binder does for us at the command line (which is quite a lot!). Replace:
with
I hope this clears it up for you. The parameter binder is probably the least visible but most powerful part of the powershell experience.
-Oisin