Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Can';将对象从.Net传输到托管powershell_C#_Powershell - Fatal编程技术网

C# Can';将对象从.Net传输到托管powershell

C# Can';将对象从.Net传输到托管powershell,c#,powershell,C#,Powershell,我想在C应用程序中执行Powershell脚本。 为此,我使用的是Microsoft.PowerShell.5.ReferenceAssemblies包(因为net48要求) 我想将对象从.Net导入脚本,但没有成功 static void Main(字符串[]args) { var runspace=RunspaceFactory.CreateRunspace(); Open(); var ps=PowerShell.Create(); ps.运行空间=运行空间; var pipeline=r

我想在
C
应用程序中执行
Powershell
脚本。 为此,我使用的是
Microsoft.PowerShell.5.ReferenceAssemblies
包(因为
net48
要求)

我想将对象从
.Net
导入脚本,但没有成功

static void Main(字符串[]args)
{
var runspace=RunspaceFactory.CreateRunspace();
Open();
var ps=PowerShell.Create();
ps.运行空间=运行空间;
var pipeline=runspace.CreatePipeline();
pipeline.Commands.AddScript(@“example.ps1”);
管道。输入。写入(“1”);
管道。输入。写入(“2”);
pipeline.Input.Flush();
var res=pipeline.Invoke();
foreach(以res表示的变量xx){
控制台写入线(xx);
}
}
示例1.ps1:

[CmdletBinding()]
param(
[参数(ValueFromPipeline=$true)]
$p
)
开始{
写入输出“开始”
}
过程{
写入输出“进程$\”
}
结束{
写入输出“结束”
}
实际产量:

Start
Process
End
预期产出:

Start
Process 1
Process 2
End

经过大量的实证测试,我发现以下方法对我有效:

pipeline.Input.Write(“1”);
管道。输入。写入(“2”);
pipeline.Commands.Add(“.\\example.ps1”);
也就是说,使用
pipeline.Commands.Add
,而不是
pipeline.Commands.AddScript
。即使您的命令是脚本文件的名称,但它是命令而不是脚本

另外,请注意
pipeline.Input.Write
位于
pipeline.Commands.Add
之前,我已经删除了
pipeline.Input.Flush()
——这些似乎都以不同的方式破坏了东西

完整代码变为:

static void Main(字符串[]args)
{
var runspace=RunspaceFactory.CreateRunspace();
Open();
var ps=PowerShell.Create();
ps.运行空间=运行空间;
var pipeline=runspace.CreatePipeline();
管道。输入。写入(“1”);
管道。输入。写入(“2”);
pipeline.Commands.Add(“.\\example.ps1”);
var res=pipeline.Invoke();
foreach(以res表示的变量xx){
控制台写入线(xx);
}
}
然后应用程序将其写入控制台:

开始
过程1
过程2
终点
其推论是,
AddScript
似乎不使用管道输入

为了完整性,下面是我一路上做的一些其他(不完整的)测试:

//失败-原始代码
//pipeline.Commands.AddScript(“.\\example.ps1”);
//管道。输入。写入(“1”);
//管道。输入。写入(“2”);
//pipeline.Input.Flush();
//开始
//过程
//结束
//测试-适用于命令,但需要脚本中的参数
//pipeline.Commands.AddScript(“1,2 |写输出”);
// 1
// 2
//测试-适用于脚本,但需要脚本中的参数
//pipeline.Commands.AddScript(“1,2 |.\\example.ps1”);
//开始
//过程1
//过程2
//结束
//测试-适用于具有管道输入的命令
//管道。输入。写入(“1”);
//管道。输入。写入(“2”);
//pipeline.Commands.Add(“写入输出”);
// 1
// 2
//测试-使用AddScript和脚本上的强制参数失败
//管道。输入。写入(“1”);
//管道。输入。写入(“2”);
//pipeline.Commands.AddScript(“写入输出”);
//System.Management.Automation.ParameterBindingException:'无法处理命令,因为
//缺少一个或多个必需参数:InputObject'
//测试-使用AddScript和脚本上的可选参数失败
//管道。输入。写入(“1”);
//管道。输入。写入(“2”);
//pipeline.Commands.AddScript(“.\\example.ps1”);
//开始
//过程
//结束
//失败-刷新杀死管道
//管道。输入。写入(“1”);
//管道。输入。写入(“2”);
//pipeline.Input.Flush();
//pipeline.Commands.Add(“.\\example.ps1”);
//开始
//过程
//结束
//失败-在脚本之后写入管道
//pipeline.Commands.AddScript(“.\\example.ps1”);
//管道。输入。写入(“1”);
//管道。输入。写入(“2”);
//开始
//过程
//结束
更新

您可以将包含PowerShell脚本的字符串转换为“可管道化”命令,如下所示(请注意
new command
-即
isScript:true
)中的第二个参数:

pipeline.Input.Write(“1”);
管道。输入。写入(“2”);
var scriptText=File.ReadAllText(“.\\example.ps1”);
pipeline.Commands.Add(
新命令(scriptText,true)
);
//开始
//过程1
//过程2
//结束

你的回答解决了我的问题。但我创建的示例不正确,收到的行为与我的应用程序中的行为“相似”。)在我的real应用程序中有一个AddScript(File.ReadAllText(“示例”)),它在问题中也有帮助,但在real应用程序中没有帮助。经过一些研究,我发现脚本只有在pipeline.input.Write为pipeline.input.Count==0时才接收输入,所以我现在在对象之间等待。你知道这种行为吗?@BorisNikitin-我为你的场景添加了一个更新。希望对你有帮助。。。