我将如何从 PowerShell 返回一个对象或多个值以执行 C# 代码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10106217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How would I return an object or multiple values from PowerShell to executing C# code
提问by Kjensen
Some C# code executes a powershell script with arguments. I want to get a returncode and a string back from Powershell to know, if everything was ok inside the Powershell script.
某些 C# 代码执行带有参数的 powershell 脚本。我想从 Powershell 获取返回码和字符串,以了解 Powershell 脚本中是否一切正常。
What is the right way to do that - in both Powershell and C#
这样做的正确方法是什么 - 在 Powershell 和 C# 中
Powershell
电源外壳
# Powershell script
# --- Do stuff here ---
# Return an int and a string - how?
# In c# I would do something like this, if this was a method:
# class ReturnInfo
# {
# public int ReturnCode;
# public string ReturnText;
# }
# return new ReturnInfo(){ReturnCode =1, ReturnText = "whatever"};
C#
C#
void RunPowershellScript(string scriptFile, List<string> parameters)
{
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
using (Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration))
{
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
Command scriptCommand = new Command(scriptFile);
Collection<CommandParameter> commandParameters = new Collection<CommandParameter>();
foreach (string scriptParameter in parameters)
{
CommandParameter commandParm = new CommandParameter(null, scriptParameter);
commandParameters.Add(commandParm);
scriptCommand.Parameters.Add(commandParm);
}
pipeline.Commands.Add(scriptCommand);
Collection<PSObject> psObjects;
psObjects = pipeline.Invoke();
//What to do here?
//ReturnInfo returnInfo = pipeline.DoMagic();
}
}
class ReturnInfo
{
public int ReturnCode;
public string ReturnText;
}
I have managed to do this is some hacky ways by using Write-Output and relying on conventions like "last two psObjects are the values I am looking for", but it would break very easily.
我已经设法通过使用 Write-Output 并依赖诸如“最后两个 psObjects 是我正在寻找的值”之类的约定来做到这一点,但它很容易中断。
采纳答案by CB.
In your powershell script you can build an Hashtable based on your necessity:
在您的 powershell 脚本中,您可以根据需要构建一个 Hashtable:
[hashtable]$Return = @{}
$Return.ReturnCode = [int]1
$Return.ReturnString = [string]"All Done!"
Return $Return
In C# code handle the Psobject in this way
在 C# 代码中以这种方式处理 Psobject
ReturnInfo ri = new ReturnInfo();
foreach (PSObject p in psObjects)
{
Hashtable ht = p.ImmediateBaseObject as Hashtable;
ri.ReturnCode = (int)ht["ReturnCode"];
ri.ReturnText = (string)ht["ReturnString"];
}
//Do what you want with ri object.
If you want to use a PsCustomobject as in Keith Hill comment in powershell v2.0:
如果你想像在 powershell v2.0 中的 Keith Hill 评论中那样使用 PsCustomobject:
powershell script:
PowerShell 脚本:
$return = new-object psobject -property @{ReturnCode=1;ReturnString="all done"}
$return
c# code:
代码:
ReturnInfo ri = new ReturnInfo();
foreach (PSObject p in psObjects)
{
ri.ReturnCode = (int)p.Properties["ReturnCode"].Value;
ri.ReturnText = (string)p.Properties["ReturnString"].Value;
}
回答by mgnoonan
Wow, good question! I'll take a shot off the top of my head...
哇,好问题!我会从头顶上开枪...
You could design a class in C# that represents the structure you want to use to pass data between the two. In the PS script, you could use an XmlWriter to craft an XML response and use Write-outputto spit out the XML string.
您可以在 C# 中设计一个类,该类表示要用于在两者之间传递数据的结构。在 PS 脚本中,您可以使用 XmlWriter 来制作 XML 响应并用于Write-output吐出 XML 字符串。
On the C# side, capture the standard out response, deserialize the XML into your new response class, and then process the result. Note that you can't write anything out to stdout other than your XML response, or else you won't be able to deserialze into the class.
在 C# 端,捕获标准输出响应,将 XML 反序列化为新的响应类,然后处理结果。请注意,除了 XML 响应之外,您不能将任何内容写入 stdout,否则您将无法反序列化到类中。
回答by hvaughan3
CB.'s answerworked great for me with a minor change. I did not see this posted anywhere (in regards to C# and PowerShell) so I wanted to post it.
CB. 的回答对我很有用,只需稍作改动。我没有在任何地方看到这个帖子(关于 C# 和 PowerShell),所以我想发布它。
In my PowerShell script I created created a Hashtable, stored 2 values in it (a Boolean and an Int) and then converted that into a PSObject:
在我的 PowerShell 脚本中,我创建了一个 Hashtable,在其中存储了 2 个值(一个 Boolean 和一个 Int),然后将其转换为一个 PSObject:
$Obj = @{}
if($RoundedResults -ilt $Threshold)
{
$Obj.bool = $true
$Obj.value = $RoundedResults
}
else
{
$Obj.bool = $false
$Obj.value = $RoundedResults
}
$ResultObj = (New-Object PSObject -Property $Obj)
return $ResultObj
And then in my C# code I did the same thing that CB. did but I had to use Convert.ToStringin order to successfully get the values back:
然后在我的 C# 代码中,我做了与 CB 相同的事情。做了,但我必须使用Convert.ToString才能成功取回值:
ReturnInfo ri = new ReturnInfo();
foreach (PSObject p in psObjects)
{
ri.ReturnCode = Convert.ToBoolean(p.Properties["ReturnCode"].Value;)
ri.ReturnText = Convert.ToString(p.Properties["ReturnString"].Value;)
}
I found the answer to this via the following StackOverflow post: https://stackoverflow.com/a/5577500
我通过以下 StackOverflow 帖子找到了答案:https://stackoverflow.com/a/5577500
Where Kieren Johnstone says:
Kieren Johnstone 说:
Use Convert.ToDouble(value) rather than (double)value. It takes an object and supports all of the types you asked for! :)
使用 Convert.ToDouble(value) 而不是 (double)value。它需要一个对象并支持您要求的所有类型!:)

