我已经在这个问题上工作了几天,并在这里阅读了几篇文章,但我无法让我的实现工作。我在Commit自定义操作期间调用powershell脚本。当我到达pipeline.Invoke()方法时,我得到一个异常,说明整个脚本“不被识别为cmdlet,函数,脚本文件或可操作程序的名称。检查名称的拼写,或者是否包含路径,验证路径是否正确,然后重试。“
这是我的剧本:
Param(
[parameter(Mandatory=$true,ValueFromPipeline=$true)]
[string]$installPath
);
schtasks /create /TN MyTask /RU domain\account /RP password /xml $installPath\MyTaskSchedule.xml;
我已经尝试过,有或没有尾随的分号,有和没有包装功能。我已经验证了C#代码正在传递正确的安装路径,并且在执行此步骤之前,xml文件存在于目录中。我可以从PowerShell本身运行它,它可以正常工作。
这是我的代码:
public override void Commit( System.Collections.IDictionary savedState )
{
base.Commit( savedState );
String targetDirectory = this.Context.Parameters["TDir"].ToString();
String script = System.IO.File.ReadAllText( targetDirectory + "TaskScheduler.ps1" );
RunspaceConfiguration c = RunspaceConfiguration.Create();
using ( Runspace runspace = RunspaceFactory.CreateRunspace() )
{
runspace.Open();
using ( Pipeline pipeline = runspace.CreatePipeline() )
{
Command myCommand = new Command( script );
CommandParameter param = new CommandParameter( "installPath", targetDirectory.Replace("\\\\", "\\") );
myCommand.Parameters.Add( param );
pipeline.Commands.Add( myCommand );
try
{
pipeline.Invoke();
}
catch ( Exception e )
{
MessageBox.Show( e.Message );
}
}
}
}
当在pipeline.Invoke捕获异常时,在上面详述的错误消息之前,将显示整个脚本(使用$ installPath而不是实际路径)作为字符串。我已经在脚本本身内尝试了几次检查,但无论如何都得到相同的结果,这告诉我,runpace只是不喜欢脚本本身。
答案 0 :(得分:0)
您应该将true
作为构造函数中的第二个参数传递:new Command(script, true)
。它告诉该命令是脚本代码,而不是命令名。
以下是代码的PowerShell模拟代码:
# This script calls the external command (cmd) with passed in parameter
$script = @'
param
(
[parameter(Mandatory=$true,ValueFromPipeline=$true)]
[string]$installPath
)
cmd /c echo $installPath
'@
# Note: the second parameter $true tells that the command is a script code, not just a command name
$command = New-Object Management.Automation.Runspaces.Command $script, $true
$param = New-Object Management.Automation.Runspaces.CommandParameter "installPath", "C:\UTIL\INSTALL"
$command.Parameters.Add($param)
$rs = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
$rs.Open()
$pipeline = $rs.CreatePipeline()
$pipeline.Commands.Add($command)
$pipeline.Invoke()
它打印(在控制台主机中):
C:\UTIL\INSTALL