Cannot process argument transformation

a 夏天 提交于 2019-12-22 06:53:56

问题


Inspired by this post, I created the script below 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

However, on execution it returns this error:

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

I've searched for this error but can't figure it out. It seems to me that it can't convert the string type correctly! Please help!


回答1:


Your best bet is to use --% in PowerShell V3 or higher. See this blog post I wrote on using --%. In V1/V2 the situation is just bad as you can see in this Connect bug on the issue. The common workaround in V1/V2 is to use Start-Process or .NET's Process.Start. From those list of workarounds, I kind of like this one:

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

Which is effectively what --% does to the parsing of all parameters following it i.e. it parses them in a dumbed down mode similar to cmd.exe parameter parsing including expanding env vars referenced with %envVarName%.




回答2:


Alright based on the answer by Keith I've modified my function as follows:

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 


来源:https://stackoverflow.com/questions/21524101/cannot-process-argument-transformation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!