【问题标题】:Limit number of Start-Process running in powershell限制在 powershell 中运行的 Start-Process 数量
【发布时间】:2018-05-04 10:01:05
【问题描述】:

我试图限制从 Powershell 运行的 Start-Process 的数量,但我似乎无法让它工作。

我尝试遵循这个过程:https://exchange12rocks.org/2015/05/24/how-to-limit-a-number-of-powershell-jobs-running-simultaneously/Run N parallel jobs in powershell

但是这些是针对 Jobs 而不是 Processes,我想从 Start-Process 中删除 -Wait

我对脚本的担心是,如果文件夹中有 1000 个音频文件,那么 FFMpeg 会导致系统崩溃。


# get the folder for conversion
function mbAudioConvert {
    [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
    [System.Windows.Forms.Application]::EnableVisualStyles()

    $fileBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
    $fileBrowser.SelectedPath = "B:\"
    $fileBrowser.ShowNewFolderButton = $false
    $fileBrowser.Description = "Select the folder with the audio which you wish to convert to Avid DNxHD 120 25P 48kHz"

    $mbLoop     = $true
    $mbCount    = 0001
    $mbMaxJob   = 4

    while( $mbLoop ) {
        if( $fileBrowser.ShowDialog() -eq "OK" ) {
            $mbLoop     = $false


            $mbImage    = ( Get-Item -Path "C:\Users\user\Desktop\lib\AudioOnly.jpg" )
            $mbff32     = ( Get-Item -Path "C:\Users\user\Desktop\lib\ffmpeg32.exe" )
            $mbff64     = ( Get-Item -Path "C:\Users\user\Desktop\lib\ffmpeg64.exe" )

            $mbFolder   = $fileBrowser.SelectedPath
            $mbItemInc  = ( ls $mbFolder\* -Include *.mp3, *.MP3, *.wav*, *.WAV*, *.ogg, *.OGG, *.wma, *.WMA, *.flac, *.FLAC, *.m4a, *.M4a )
            $mbProgress = ( Get-ChildItem -Path $mbItemInc )

            $mbHasRaw   = ( $mbFolder + "\RAW" )

            if( !( Test-Path -Path $mbHasRaw ) ) {
                # force create a RAW folder if it does not exist
                New-Item -ItemType Directory -Force -Path "$mbHasRaw"
            }


            foreach( $mbItem in $mbItemInc ) {

                $mbCheck    = $false

                # output the progress
                # Suggestion: You might want to consider updating this after starting the job and do the final update after running ex. Get-Job | Wait-Job to make the progress-bar stay until all processes are finished
                #Write-Progress -Activity "Counting files for conversion" -status "Currently processing: $mbCount" -percentComplete ($mbCount / $mbItemInc.count*100)

                # limit the run number
                while ($mbCheck -eq $false) {

                    if( (Get-Job -State 'Running').count -lt $mbMaxJob) {

                        $mbScriptBlock = {
                            $mbItemName = $using:mbItem.BaseName

                            $mbNewItem  = ( $using:mbFolder + "\RAW\" + $mbItemName + ".mov" )
                            $mbArgs     = " -loop 1 -i $using:mbImage -i $using:mbItem -shortest -c:v dnxhd -b:v 120M -s 1920x1080 -pix_fmt yuv422p -r 25 -c:a pcm_s16le -ar 48k -af loudnorm=I=-12 $mbNewItem"

                            Start-Process -FilePath $using:mbff32 -ArgumentList $mbArgs -NoNewWindow -Wait
                        }

                        Start-Job -ScriptBlock $mbScriptBlock

                        #The job-thread doesn't know about $mbCount, better to increment it after starting the job
                        $mbCount++
                        $mbCheck  = $true          
                    }

                }
            }

        } else {

            $mbResponse = [System.Windows.Forms.MessageBox]::Show("You have exited out of the automation process!", "User has cancelled")
            if( $mbResponse -eq "OK" ) {
                return
            }
        }
    }

    $fileBrowser.SelectedPath
    $fileBrowser.Dispose()
}

# call to function
mbAudioConvert

【问题讨论】:

  • 您需要-Wait 知道进程何时结束,以便计算并发进程。另一种方法是Get-Process-loop。为什么不使用您在作业脚本块中使用Star-Process -Wait 描述的作业?
  • @FrodeF。我还真想不通。每次我尝试通过作业运行它时,它都不会从脚本块中的 Start-Process 进行视频转换
  • 使用该尝试的代码、错误和预期行为更新问题,以便我们帮助您进行故障排除。我们在这里帮助您修复自己的代码,而不是为您编写代码。
  • @FrodeF。我添加了我尝试使用的脚本部分

标签: powershell ffmpeg powershell-2.0 start-job start-process


【解决方案1】:
  1. 您编辑了$mbCheck,但while 循环正在测试$Check,这意味着当$Check 未定义时,while 循环将永远不会执行,因为$Check -eq $false$false
  2. 在作业脚本块之外创建的变量需要作为参数传递,或者您需要使用using: 变量范围来传递它们(PowerShell 3.0 或更高版本)。将其添加到示例中未定义的$mbItem$mbff32$mbImage$mbFolder
  3. $mbMaxJob 未定义。 get running jobs-check 永远不会为真,并且不会启动任何进程
  4. $mbCount 未定义。进度条不起作用
  5. echo "$mbCount. $mbNewItem" 不会返回任何内容,除非您在某些时候使用 Receive-Job 从作业中获取输出

试试:

#DemoValues
$mbItemInc = 1..10 | % { New-Item -ItemType File -Name "File$_.txt" }
$mbff32 = "something32"
$mbFolder = "c:\FooFolder"
$mbImage = "BarImage"
$mbMaxJob = 2
$mbCount = 0

foreach( $mbItem in $mbItemInc ) {

    $mbCheck    = $false

    # output the progress
    # Suggestion: You might want to consider updating this after starting the job and do the final update after running ex. Get-Job | Wait-Job to make the progress-bar stay until all processes are finished
    Write-Progress -Activity "Counting files for conversion" -status "Currently processing: $mbCount" -percentComplete ($mbCount / $mbItemInc.count*100)

    # limit the run number
    while ($mbCheck -eq $false) {

        if ((Get-Job -State 'Running').count -lt $mbMaxJob) {

            $mbScriptBlock = {

                 Param($mbItem, $mbFolder, $mbImage, $mbff32)
                #Filename without extension is already available in a FileInfo-object using the BaseName-property
                $mbItemName = $mbItem.BaseName

                $mbNewItem  = ( $mbFolder + "\RAW\" + $mbItemName + ".mov" )
                $mbArgs     = "-loop 1 -i $mbImage -i $mbItem -shortest -c:v dnxhd -b:v 120M -s 1920x1080 -pix_fmt yuv422p -r 25 -c:a pcm_s16le -ar 48k -af loudnorm=I=-12 $mbNewItem"

                Start-Process -FilePath $mbff32 -ArgumentList $mbArgs -NoNewWindow -Wait
            }

            Start-Job -ScriptBlock $mbScriptBlock -ArgumentList $mbItem, $mbFolder, $mbImage, $mbff32

            #The job-thread doesn't know about $mbCount, better to increment it after starting the job
            $mbCount++
            $mbCheck  = $true          
        }

    }
}

【讨论】:

  • 我已经更新了问题中的代码,让您参与其中。仍然无法运行,但也许完整的代码可以提供帮助?
  • 您的$mbMaxJob 定义在哪里?
  • 抱歉,复制粘贴出错。它在$mbCount下的顶部
  • 您运行的是哪个 PSVersion?我提到$using: 是 3.0+ 的功能,但您的问题被标记为 2.0。还。尝试在脚本中添加一些 cmets,例如 "before while-loop $mbItem""starting job $mbItem",这样您就可以确定它停止的位置。进度条是移动还是停留在第一个状态?
  • 如前所述,$using: 不适用于 PS2.0。我已经更新了答案以使其支持 2.0。不过,您应该更新 Powershell,因为它带来了很多好处
【解决方案2】:

我建议你我的解决方案:

cls

$FormatNameJob="FFMPEG"
$maxConcurrentJobs = 100
$DirWithFile="C:\temp"
$DestFolder="C:\temp2"
$TraitmentDir="C:\temp\traitment"
$PathFFMpeg="C:\Temp\ffmpeg\ffmpeg\bin\ffmpeg.exe"
$HistoFolder="C:\temp\histo"

#create dir if dont exists
New-Item -ItemType Directory -Path $TraitmentDir -Force | Out-Null
New-Item -ItemType Directory -Path $DestFolder -Force | Out-Null
New-Item -ItemType Directory -Path $HistoFolder -Force | Out-Null


while ($true)
{
    "Loop File"

    $ListeFile=Get-ChildItem $DirWithFile -file -Filter "*.avi"

    if ($ListeFile.count -eq 0 )
    {
       Start-Sleep -Seconds 1
       continue 
    }

    #loop file to trait
    $ListeFile | %{

        while ((get-job -State Running | where Name -eq $FormatNameJob ).Count -ge $maxConcurrentJobs)
        {
            Start-Sleep -Seconds 1
            get-job -State Completed | where Name -eq $FormatNameJob | Remove-Job
        }

        "traitment file : {0}" -f $_.Name

        #build newname and move item into traitment dir
        $NewfileName="{0:yyyyMMddHHmmssfffff}_{1}" -f (get-date), $_.Name
        $ItemTraitment=[io.path]::Combine($TraitmentDir, $NewfileName)
        $mbNewItem  ="{0}.mov" -f [io.path]::Combine($DestFolder, $_.BaseName)
        Move-item $_.FullName -Destination $ItemTraitment

        #build arguments and command
        $mbArgs     = " -loop 1 -i $ItemTraitment -shortest -c:v dnxhd -b:v 120M -s 1920x1080 -pix_fmt yuv422p -r 25 -c:a pcm_s16le -ar 48k -af loudnorm=I=-12 $mbNewItem"

        $ScriptBlock=[scriptblock]::Create("Start-Process $PathFFMpeg -ArgumentList $mbArgs -Wait")

        #add job
        Start-Job -ScriptBlock $ScriptBlock -Name $FormatNameJob
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-18
    • 2015-08-12
    • 1970-01-01
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 2020-08-17
    相关资源
    最近更新 更多