Start-Process с приоритетом процесса в L oop не распознает переменную - PullRequest
0 голосов
/ 29 мая 2020

Я использую FFmpeg с PowerShell.

У меня есть al oop, который просматривает папку mpg файлов и захватывает имена в переменную $inputName.

FFmpeg затем преобразует каждый из них в mp4.


Работает

Пакетная обработка

$files = Get-ChildItem "C:\Path\" -Filter *.mpg; 

foreach ($f in $files) {

    $inputName = $f.Name; #name + extension
    $outputName = (Get-Item $inputName).Basename; #name only

    ffmpeg -y -i "C:\Users\Matt\Videos\$inputName" -c:v libx264 -crf 25 "C:\Users\Matt\Videos\$outputName.mp4"
}

Не работает

Пакетная обработка с приоритетом процесса

$files = Get-ChildItem "C:\Path\" -Filter *.mpg; 

foreach ($f in $files) {

    $inputName = $f.Name; #name + extension
    $outputName = (Get-Item $inputName).Basename; #name only

    ($Process = Start-Process ffmpeg -NoNewWindow -ArgumentList '-y -i "C:\Users\Matt\Videos\$inputName" -c:v libx264 -crf 25 "C:\Users\Matt\Videos\$outputName.mp4"' -PassThru).PriorityClass = [System.Diagnostics.ProcessPriorityClass]::AboveNormal;
    Wait-Process -Id $Process.id 

}

Если я установил приоритет процесса с помощью Start-Process PriorityClass, переменная $inputName больше не распознается.

Error:
C:\Users\Matt\Videos\$inputName: No such file or directory

1 Ответ

1 голос
/ 29 мая 2020

Позволяет go несколько основных c вещей.

В PowerShell мы любим конвейер |, он позволяет использовать для передачи информации от одной команды к другой команде.

Хорошим примером этого является ForEach, который у вас есть.

Вместо Foreach($F in $Files) вы можете передать | в foreach-object

Get-ChildItem "C:\Path\" -Filter *.mpg | Foreach-Object{
    $_
}

При прокладке трубопровода | командная оболочка powershell автоматически создает переменную $_, которая является объектом, который передается в конвейере |

Следующее, что есть 2 типа кавычек " и '.

Если вы используете ', то все понимается буквально. Пример:

$FirstName = "TestName"
'Hey There $FirstName'

Вернет

Hey There $FirstName

Хотя " позволяет вам использовать в нем переменные. Пример:

$FirstName = "TestName"
'Hey There $FirstName'

Вернет

Hey There TestName

И последнее, прежде чем мы это исправим. В powershell у нас есть escape-символ, известный как галочка. Он расположен рядом с цифрой 1 на клавиатуре с тильдой. Вы используете его, чтобы разрешить использование char, которое в противном случае вырвалось бы из кавычек. Пример:

"`"Hey There`""

Вернет

"Hey There"

ОК, так что теперь, когда мы рассмотрели основы, давайте исправим сценарий

Get-ChildItem "C:\Users\Matt\Videos\" -Filter *.mpg -File | Foreach-Object{
    ($Process = Start-Process ffmpeg -NoNewWindow -ArgumentList "-y -i `"$($_.FullName)`" -c:v libx264 -crf 25 `"C:\Users\Matt\Videos\$($_.Name)`"" -PassThru).PriorityClass = [System.Diagnostics.ProcessPriorityClass]::AboveNormal;
    Try{
        Wait-Process -Id $Process.id
    }catch{
    }
}

В приведенном выше случае я изменил

Добавьте -File к Get-ChildItem, чтобы указать, что вам нужны только файлы, возвращаемые, а не папки

Труба | в Foreach-Object

Изменены внешние скобки в -ArgumentList должны быть двойными кавычками " вместо буквальных кавычек '

Удалены $InputName и $OutputName в пользу переменной Foreach-Object $_

...