【问题标题】:Cannot process argument transformation无法处理参数转换
【发布时间】:2014-02-26 17:55:23
【问题描述】:

post的启发,我在DOSCommands.ps1下面创建了脚本

Function Invoke-DOSCommands {
    Param(
        [Parameter(Position=0,Mandatory=$true)]
        [String]$cmd,
        [String]$tmpname = $(([string](Get-Random -Minimum 10000 -Maximum 99999999)) + ".cmd"),
        [switch]$tmpdir = $true)
    if ($tmpdir) {
        $cmdpath = $(Join-Path -Path $env:TEMP -ChildPath $tmpname);
    }
    else {
        $cmdpath = ".\" + $tmpname
    }
    Write-Debug "tmpfile: " + $cmdpath
    Write-Debug "cmd: " + $cmd
    echo $cmd | Out-File -FilePath $cmdpath -Encoding ascii;
    & cmd.exe /c $cmdpath | Out-Null
}

Invoke-DOSCommands "Echo ""Hello World""", -tmpdir $false

但是,在执行时它会返回此错误:

Invoke-DOSCommands : Cannot process argument transformation on parameter 'cmd'. Cannot convert value to type S ystem.String.
At DOSCommands.ps1:20 char:19
+ Invoke-DOSCommands <<<<  "Echo ""Hello World""", -tmpdir $false
    + CategoryInfo          : InvalidData: (:) [Invoke-DOSCommands], ParameterBindin...mationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Invoke-DOSCommands

我已经搜索过这个错误,但无法弄清楚。在我看来,它无法正确转换字符串类型!请帮忙!

【问题讨论】:

  • 在要作为参数传递的字符串后面有一个逗号$Cmd
  • 如果你使用的是PS V3,你可以使用转义符--%

标签: powershell powershell-2.0


【解决方案1】:

最好的办法是在 PowerShell V3 或更高版本中使用 --%。看到这个blog post 我使用--% 写的。在 V1/V2 中,情况很糟糕,正如您在 Connect bug on the issue 中看到的那样。 V1/V2 中常见的解决方法是使用 Start-Process 或 .NET 的 Process.Start。从这些解决方法列表中,我有点喜欢这个:

[System.Diagnostics.Process]::Start("Cmd", "/c anything you want to put here with embedded quotes, and variables")

这实际上是--% 对解析它后面的所有参数所做的,即它以类似于 cmd.exe 参数解析的简化模式解析它们,包括扩展 %envVarName% 引用的环境变量。

【讨论】:

  • 谢谢!这行得通。但是在启动 cmd.exe 的时候,我们如何使用 comspec 变量并保证和当前的 powershell 脚本工作目录相同呢?
  • @Vijay 如果您使用采用StartProcessInfo 对象的Start 重载,您可以在该StartProcessInfo 对象中设置WorkingDirectory
  • 文档Process.startProcess.StartInfo。我猜这就是你的意思。
  • 是的,StartInfo 上有一个 WorkingDirectory 属性。您创建一个实例并将其作为参数传递给 Process.Start()。
【解决方案2】:

好吧,根据 Keith 的回答,我已将函数修改如下:

Function Invoke-DOSCommands {
    Param(
        [Parameter(Position=0,Mandatory=$true)]
        [String]$cmd)

    $comspec =  $env:comspec # have to get comspec
    $cwd = Get-Location # ensure correct working directory
    $pstartinfo = new-object -type System.Diagnostics.processStartInfo -Argumentlist "$comspec","/c $cmd"
    $pstartinfo.WorkingDirectory= $cwd
    Write-Debug "cmd: $pstartinfo.FileName"
    Write-Debug "args: $pstartinfo.Arguments"
    Write-Debug "dir: $pstartinfo.WorkingDirectory"
    #[System.Diagnostics.Process]::Start("Cmd", "/c $cmd")
    [System.Diagnostics.Process]::Start($pstartinfo)
}

Invoke-DOSCommands "Echo ""Hello World"" & dir & pause" # testing function 

【讨论】:

    猜你喜欢
    • 2015-01-21
    • 2021-11-22
    • 2023-03-29
    • 2021-05-22
    • 2017-08-22
    • 2022-01-12
    • 2015-01-11
    • 2015-05-14
    • 2014-05-31
    相关资源
    最近更新 更多