我在C#中有一个简单的函数来调用PowerShell命令并返回输出,它运行良好。但是,我希望能够为添加到PowerShell的自定义函数返回值。这是我的C#代码:
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = runspace;
ps.Commands.AddScript("MyCustomCommand");
ICollection<PSObject> results = ps.Invoke();
当我在本地运行PowerShell时,我在C:WindowsSystem32WindowsPowerShellv1.0Microsoft.PowerShell_profile.ps1
位置设置了配置文件,所以当我打开PowerShell并输入MyCustomCommand
时,它会返回一个字符串:
Function MyCustomCommand {
[CmdletBinding()]
param()
return "someoutput"
}
然而,当我从C#调用相同的MyCustomCommand时,却找不到它。如何永久添加此配置文件,使C#在调用命令时也能返回相同的输出,就像我在桌面上打开PowerShell实例时一样?
更新我使用了@start automatics推荐的模块解决方案,但由于执行策略的原因,我无法运行,所以我修改了它:
ps.Runspace = runspace;
ps.AddCommand("Set-ExecutionPolicy").AddArgument("Unrestricted");
ps.AddCommand("Import-Module").AddArgument("MyNewModuleName");
ps.Commands.AddScript("MyCustomCommand");
出了什么问题
它无法在C#中运行您的命令,因为您的命令尚未加载。
好的,那么你是如何加载的
您已经在使用[Runspace]
。这很好。[Runspace]
是您将函数加载到其中所需要的。有两种方法可以做到这一点:
- 使用
[InitialSessionState]
这是推荐的路线。CCD_ 6用于填充PowerShell[Runspace]
的初始状态。在这里,您可以加载模块、声明命令、添加变量等。最简单的处理方法是首先将它们放在模块中。
InitialSessionState iss = InitialSessionState.CreateDefault2();
// Note: .CreateDefault2 is the recommended default of a session state
// Note: .CreateDefault reflects the default session state in v2-v4 timeframes
iss.ImportPSModule(new[] { "NameOfModule" });
iss.ImportPSModulesFromPath("PathToModule");
Runspace runspace = RunspaceFactory.CreateRunspace(iss);
您也可以使用SessionStateFunctionEntry 手工声明单个函数
InitialSessionState iss = InitialSessionState.CreateDefault2();
iss.Commands.Add(new SessionStateFunctionEntry("MyFunction","MyDefinition"));
使用任何一种技术,都应该用您需要的命令填充您的运行空间。
useLocalScope设置为$false的.AddCommand/.AddScript另一种方法是运行一个命令来更改[Runspace]
。默认情况下,当将.AddCommand或.AddScript添加到[PowerShell]
对象时,它将使用";本地";范围这意味着您所做的任何更改(添加的命令、导入的模块、设置的变量等(都将是";"局部作用域";,并且下次在[Runspace]
中运行时将不可用。
若要使其按您希望的方式工作,请在useLocalScope(第二个参数(设置为false的情况下使用.AddScript/.AddCommand。
以下是PowerShell概念的快速验证:
[PowerShell]::Create().AddScript('$x = 1',$false).AddStatement().AddScript('$x').Invoke()
希望这能帮助