`Start-Process` 找不到存在于 PATH 中的文件,即使给定了文件的绝对路径

`Start-Process` can not find file that exists in PATH, even when given absolut path to the file

我正在尝试在 Powershell Core 中使用 Start-Process,使用一个变量来指定要启动的进程。我知道 dotnet 在我的 PATH 中,所以这有效:

$DotnetRunCommandApp = 'run --project path/to/my/project.csproj'
Start-Process dotnet -ArgumentList $DotnetRunCommandApp

但是,当我尝试将 dotnet 移动到这样的变量中时:

$DotnetCommand = 'dotnet'
$DotnetRunCommandApp = 'run --project path/to/my/project.csproj'
Start-Process $DotnetCommand -ArgumentList $DotnetRunCommandApp

甚至像这样使用 dotnet 的绝对路径:

$DotnetCommand = Resolve-Path ((Get-Command dotnet).Source | Out-String -NoNewline)

if (-not (Test-Path $DotnetCommand)) {
  Write-Error "Can not find '$DotnetCommand'"
} else {
  Write-Debug "Found $DotnetCommand" # Logs "DEBUG: Found C:\Program Files\dotnet\dotnet.exe"
}

$DotnetRunCommandApp = 'run --project path/to/my/project.csproj'
Start-Process $DotnetCommand -ArgumentList $DotnetRunCommandApp

我得到一个 InvalidOperationException:

This command cannot be run due to the error: The system cannot find the file specified.

不知道为什么 Start-Process 找不到该文件,尽管它确实存在于我的 PATH 中,甚至当我为 cmdlt 提供完整路径时也是如此。


我的最终目标是能够在对象中指定参数,然后将该对象传递给 Start-Process。这是在我的构建代理上运行以测试 webjob 模板的 pwsh 脚本的一部分。虽然我希望本地行为略有不同,但请参阅下面的开关 $Azure

$StartProcessParams = @{
  FilePath               = $DotnetCommand
  ArgumentList           = $DotnetRunCommandApp
  RedirectStandardError  = (Resolve-Path $WebJobErrorLogFile)
  RedirectStandardOutput = (Resolve-Path $WebJobLogFile)
  PassThru               = $true;

  # Logging works best if we keep the process in the same "window" on Azure. Locally let the
  # WebJob run in a new windows to make it really easy to kill the process in case of any errors
  NoNewWindow            = $Azure;
}

$WebJobProcess = Start-Process $StartProcessParams

根据 Start-Process 的帮助文档

If you specify only a filename, use the WorkingDirectory parameter to specify the path."

The WorkingDirectory Paramter "specifies the location of the executable file or document that runs in the process. The default is the current folder."

尝试以下命令:

Start-Process $DotnetCommand -ArgumentList $DotnetRunCommandApp -WorkingDirectory </dir/to/PATH>

您的问题可能是它试图从您的当前目录而不是您的 PATH 位置解析变量内容 'dotnet'。

正如@iRon 在评论中指出的那样,问题是我没有正确使用 splatting。我使用 $StartProcessParams 而不是 @StartProcessParams(区别在于第一个字符;$@)。这很好用:

$StartProcessParams = @{
  FilePath               = $DotnetCommand
  ArgumentList           = $DotnetRunCommandApp
  RedirectStandardError  = (Resolve-Path $WebJobErrorLogFile)
  RedirectStandardOutput = (Resolve-Path $WebJobLogFile)
  PassThru               = $true;

  # Logging works best if we keep the process in the same "window" on Azure. Locally let the
  # WebJob run in a new windows to make it really easy to kill the process in case of any errors
  NoNewWindow            = $Azure;
}

$WebJobProcess = Start-Process @StartProcessParams