Запуск .exe для получения строкового вывода не сохраняется в строковую переменную - PullRequest
1 голос
/ 09 мая 2020

Простите, я вообще новичок в PowerShell. Я обновляю процесс сборки, работающий на Linux (в bash), на тот, который будет работать на Windows в PowerShell.

Моя цель - получить версию игрового движка, которая присутствует в настоящее время в системе сборки. Расположение сборки по умолчанию хорошо известно, поэтому мы пытаемся выполнить его и получить версию, например:

$Version = & 'C:\Program Files\LOVE\love.exe' --version

Когда это выполняется, значение $Version пусто:

Write-Output $Version
[no output]

$Version -Eq $True 
False

Если я запускаю свой исполняемый файл непосредственно из оболочки, я замечаю, что строка не отображается в новой строке:

PS C:\Users\robbm\Myproject\Mygame> $Version = & 'C:\Program Files\LOVE\love.exe' --version
PS C:\Users\robbm\Myproject\Mygame> LOVE 11.3 (Mysterious Mysteries)

Это заставляет меня подозревать, что в первую очередь существует какое-то странное поведение вывода с исполняемым файлом . Это проблема с выводом LÖVE --version, или я неправильно понимаю перенаправление вывода в PowerShell? Я пробовал несколько вещей для захвата вывода, и $Version всегда, кажется, заканчивается нулевым значением, например:

$Version = & '\\build\love\love.exe' '--version' | Out-String
Write-Output $Version
$Version = (& '\\build\love\love.exe' '--version' | Out-String)
Write-Output $Version

Помощь приветствуется. Поскольку это работает для других командлетов, я склонен полагать, что это может быть функция LÖVE, но я был бы признателен за мысли о том, как я мог бы работать с этим в любом случае, или любой метод, с помощью которого можно записать версию, которую он явно выводит в экран, когда я выполняю его напрямую, независимо.

EDIT:

LÖVE определенно делает что-то другое в отношении работы на Windows. Глядя на источник печати версии , мы работаем с метко названным LOVE_LEGENDARY_CONSOLE_IO_HACK включенным на Windows, что, похоже, полностью открывает новую консоль, возможно, в cmd и напишите там.

Выполняя предложения комментаторов, я пробовал использовать метод .Exception.Message, но его нет при таком вызове:

$Version = &('C:\Program Files\LOVE\love.exe' '--version').Exception.Message

Так что я все еще ищу о способах заставить эту работу работать в рамках LÖVE, собирающего вместе какой-то странный поток ввода-вывода. *

Таким образом, это выглядит чрезмерно хакерским со стороны LÖVE, а не проблемой PowerShell.

1 Ответ

2 голосов
/ 10 мая 2020

После прочтения вашего последнего редактирования это, вероятно, не поможет вам, но может помочь другим.

Вы можете попытаться записать результат следующим образом:

function runCmdAndCaptureOutput(
    [Parameter(Mandatory=$true)]
    [string] $cmd
) {
    [string] $errOut
    [string] $stdOut
    # Deliberately dropped '$' from vars below. 
    Invoke-Expression $cmd -ErrorVariable errOut -OutVariable stdOut   
    if($LASTEXITCODE -ne 0) {
        Write-Host -ForegroundColor Red "LASTEXITCODE: $LASTEXITCODE"
        throw $LASTEXITCODE
    } 
    return $stdOut
}

$exeCmd = "'C:\Program Files\LOVE\love.exe' --version"
$output = runCmdAndCaptureOutput -cmd $exeCmd
Write-Host $output
...