Как передать смесь строк и массивов в исполняемый файл из PowerShell? - PullRequest
0 голосов
/ 29 апреля 2019

Я пытаюсь вызвать vswhere.exe на , чтобы найти различные исполняемые файлы Visual Studio для целей CI. Чтобы упростить это, я создал функцию-обертку:

function Run-VsWhere { &("${env:ProgramFiles(x86)}/Microsoft Visual Studio/Installer/vswhere.exe") $args }

function Find-VSWherePath([string[]] $workloads, [string] $pathGlob) {
    Run-VsWhere -products * -prerelease -latest -requires $workloads -requiresAny -find $pathGlob
}

Это прекрасно работает для отдельных рабочих нагрузок, например для MSBuild:

Find-VSWherePath "Microsoft.Component.MSBuild" "MSBuild/**/Bin/MSBuild.exe"
> C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Current\Bin\MSBuild.exe

... но распадается на несколько таких, как VSTest:

Find-VSWherePath "Microsoft.VisualStudio.Workload.ManagedDesktop","Microsoft.VisualStudio.Workload.Web" "**/TestPlatform/vstest.console.exe"
> (nothing)

Если я заменим вызов на vswhere на вызов на echoargs, это точно покажет, что происходит не так. MSBuild:

> Arg 0 is <-products>
> Arg 1 is <*>
> Arg 2 is <-prerelease>
> Arg 3 is <-latest>
> Arg 4 is <-requires>
> Arg 5 is <Microsoft.Component.MSBuild>
> Arg 6 is <-requiresAny>
> Arg 7 is <-find>
> Arg 8 is <MSBuild/**/Bin/MSBuild.exe>

против VSTest:

> Arg 0 is <-products>
> Arg 1 is <*>
> Arg 2 is <-prerelease>
> Arg 3 is <-latest>
> Arg 4 is <-requires>
> Arg 5 is <Microsoft.VisualStudio.Workload.ManagedDesktop Microsoft.VisualStudio.Workload.Web>
> Arg 6 is <-requiresAny>
> Arg 7 is <-find>
> Arg 8 is <**/TestPlatform/vstest.console.exe>

Проблема заключается в том, что параметр $workloads передается в Run-VsWhere как единственный параметр , объединенный пробелом , вместо одного параметра на элемент в массиве - как я могу заставить его пройти, как мне нужно? Я пробовал каждую комбинацию разделения, разделения, объединения, одинарных кавычек, двойных кавычек ... но, похоже, ничего не работает.

Ответы [ 2 ]

1 голос
/ 30 апреля 2019

Используя автоматическую переменную $args, аргументы передаются в том виде, в котором они указаны, это означает, что аргумент массива, вложенный в $args, передается как есть (то есть остается массивом).Используйте splatting (@args), чтобы сгладить / развернуть вложенные массивы.

function Run-VsWhere {
    & "${env:ProgramFiles(x86)}/Microsoft Visual Studio/Installer/vswhere.exe" @args
}
0 голосов
/ 29 апреля 2019

Возможно ли, что ваш второй вызов Find-VSWherePath ни к чему не приведет, потому что указанные рабочие нагрузки недоступны?Я попробовал код ниже и он работает.

function Find-VSWherePath([string[]] $workloads, [string] $pathGlob) {
    . "${env:ProgramFiles(x86)}/Microsoft Visual Studio/Installer/vswhere.exe" -products * -prerelease -latest -requires $workloads -requiresAny -find $pathGlob
}

clear

"This works"
Find-VSWherePath "Microsoft.Component.MSBuild" "MSBuild/**/Bin/MSBuild.exe"

"No result"
Find-VSWherePath "Microsoft.VisualStudio.Workload.Web" "MSBuild/**/Bin/MSBuild.exe"

"Try two workloads, the first is not available, but the second is. This also works."
Find-VSWherePath "Microsoft.VisualStudio.Workload.Web","Microsoft.VisualStudio.Component.NuGet" "MSBuild/**/Bin/MSBuild.exe"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...