如何从PowerShell返回一个对象或多个值以执行C#代码
一些C#代码执行带有参数的powershell脚本。我想从Powershell获取返回代码和字符串,以了解Powershell脚本中是否一切正常 在Powershell和C中,正确的方法是什么# 动力壳 C#如何从PowerShell返回一个对象或多个值以执行C#代码,c#,powershell,C#,Powershell,一些C#代码执行带有参数的powershell脚本。我想从Powershell获取返回代码和字符串,以了解Powershell脚本中是否一切正常 在Powershell和C中,正确的方法是什么# 动力壳 C# void RunPowershellScript(字符串脚本文件,列表参数) { RunspaceConfiguration RunspaceConfiguration=RunspaceConfiguration.Create(); 使用(Runspace Runspace=Runspac
void RunPowershellScript(字符串脚本文件,列表参数)
{
RunspaceConfiguration RunspaceConfiguration=RunspaceConfiguration.Create();
使用(Runspace Runspace=RunspaceFactory.CreateRunspace(runspaceConfiguration))
{
Open();
RunspaceInvoke scriptInvoker=新的RunspaceInvoke(运行空间);
Pipeline Pipeline=runspace.CreatePipeline();
命令scriptCommand=新命令(脚本文件);
Collection commandParameters=new Collection();
foreach(参数中的字符串scriptParameter)
{
CommandParameter commandParm=新CommandParameter(null,scriptParameter);
commandParameters.Add(commandParm);
scriptCommand.Parameters.Add(commandParm);
}
pipeline.Commands.Add(scriptCommand);
对象集合;
psObjects=pipeline.Invoke();
//在这里做什么?
//ReturnInfo ReturnInfo=pipeline.DoMagic();
}
}
类返回信息
{
公共代码;
公共字符串返回文本;
}
通过使用写输出和依赖“最后两个PSObject是我要寻找的值”等约定,我成功地做到了这一点,但它很容易崩溃。哇,好问题!我会在头顶上开一枪 您可以在C#中设计一个类,该类表示要用于在两者之间传递数据的结构。在PS脚本中,可以使用XmlWriter创建XML响应,并使用
Write output
输出XML字符串
在C端,捕获标准输出响应,将XML反序列化到新的响应类中,然后处理结果。请注意,除了XML响应之外,您不能将任何内容写入stdout,否则您将无法反序列化到类中。在powershell脚本中,您可以根据需要构建哈希表:
[hashtable]$Return = @{}
$Return.ReturnCode = [int]1
$Return.ReturnString = [string]"All Done!"
Return $Return
在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.
如果要使用powershell v2.0中Keith Hill注释中的PsCustomobject:
powershell脚本:
$return = new-object psobject -property @{ReturnCode=1;ReturnString="all done"}
$return
c#代码:
只做了一点小小的改变,对我来说效果很好。我没有在任何地方看到这篇文章(关于C#和PowerShell),所以我想发布它
在我的PowerShell脚本中,我创建了一个哈希表,在其中存储了2个值(布尔值和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
然后在我的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;)
}
我通过以下StackOverflow帖子找到了答案:
Kieren Johnstone说:
使用Convert.ToDouble(value)而不是(double)value。这需要一段时间
对象并支持您要求的所有类型!:)
正如您所准备的那样,
Invoke
返回一个包含管道输出的对象数组。如果管道没有输出,则返回emptycollection。所以我不确定你期望什么。。。你是在问如何调整你的powershell以返回你期望的值吗?Joshua Drake>>我在powershell脚本注释中添加了一点c,我希望这能让它更清楚,我想要什么。:)需要帮忙吗?约书亚·德雷克>>会的!现在我只需要找出另一半——如何从C#code中读取它。你应该能够在调试器中检查psObjects
,看看你是否有一些通用字典对象,或者具有特定结构的对象,然后解决这个问题。这样,你不仅可以设置任何类的字段hashtable@vittore对事实上,在V3上,使用pscustomobject$return=new-object-psobject-property@{ReturnCode=1;Result=“all done”}
和C#4的动态关键字应该会更容易。你知道,因为V3现在是基于DLR的。如果PowerShell脚本实例调用Write Host,则ImmediateBaseObject为null。模式匹配应在C#中使用。示例:如果(p.ImmediateBaseObject是哈希表ht){…}
ReturnInfo ri = new ReturnInfo();
foreach (PSObject p in psObjects)
{
ri.ReturnCode = (int)p.Properties["ReturnCode"].Value;
ri.ReturnText = (string)p.Properties["ReturnString"].Value;
}
$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
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;)
}