我想从一个 Powershell 运行两个任务,非常感谢一位成员为我提供了答案。为了简单起见,他们使用/复制了我引用的 Start-Sleep 例程。我认为这只是用所需脚本的链接替换所述例程的简单情况。你错得有多离谱?
因此,为了在原始进程中运行进度条字幕的同时在后台运行程序,他们使用了“jobs”和“ScriptBlock”...但我发现无法直接处理变量和标志...这就是为什么我现在被难住了(又一次!第三次!)我认为答案在于$ARGS(x) 和 -ArgumentList,但没有进一步的进展。
这是需要作为后台作业运行的“有趣”的命令。
& $outpath -i $file -c:a libmp3lame -q:a 4 $saveOut -nostats -loglevel warning;
=== MY_DiRECTORY\ffmpeg\ffmpeg.exe -i $file -c:a libmp3lame -q:a 4 $saveOut -nostats -loglevel warning
** 从作为单线程脚本运行时有效的行复制而来。(运行大约需要 20 秒,因此我想添加进度条以显示它没有停滞)
如您所见,我不仅要将“$outpath”、“$file”和“$saveOut”传递给后台作业(可能需要进入 param{} 区域),还有许多其他标志和单词必须作为一行传递并“执行”。顺便说一句,$outpath 是动态创建的,而 $file /$saveOut 来自用户通过标准 Windows 对话框输入的字段
我喜欢把事情弄复杂(尽管对于更有知识的人来说这可能只是“小学生的东西”)!
如果原作者注意到了这一点(js****er),我就必须以“访客”身份发布这些内容,因此无法访问论坛等其他功能。当我登录我的普通帐户时,我无法提问,而且声望值为 15,不会出现投票。
++++ 8 月 14 日更新+++++
经过=大量=次反复试验后,我最终得出了以下代码:
$ArguementList='-i "{0}" -c:a libmp3lame -q:a 4 "{1}" -loglevel quiet -stats' -f $file, $saveOut
$ProgressBar = New-Object System.Windows.Forms.ProgressBar
$ProgressBar.Location = New-Object System.Drawing.Point(10, 35)
$ProgressBar.Size = New-Object System.Drawing.Size(460, 40)
$ProgressBar.Style = "Marquee"
$ProgressBar.MarqueeAnimationSpeed = 20
$main_form.Controls.Add($ProgressBar);
$V2ALabel.Font = $procFont
$V2ALabel.ForeColor = 'red'
$V2ALabel.Text = "Processing ..."
$process=Start-Process -filePath "$ScriptDir\ffmpeg\ffmpeg.exe" $ArguementList -PassThru -WindowStyle hidden
do{
[System.Windows.Forms.Application]::DoEvents()
}
until ($process.ExitCode -eq 0)
我并不是说这是事实(仅基于我的试验),但似乎 Windows 上的 FFMPEG 必须有一个窗口来运行,因此不可能作为后台作业运行。因此,“-WindowsStyle hidden”代码会打开一个用户无法看到的窗口(但从编程上讲,它仍然可以运行)
然后它在“Do”语句中一次又一次地循环,以保持表单的进度条运行。脚本完成后,隐藏窗口“关闭”并被删除。这会生成 ExitCode 0。由于“until”表示“(执行循环)直到 ExitCode 等于 0”,因此循环终止,并执行其余代码
答案1
$using 变量范围应该在这里有所帮助,尝试这样的事情
$outpath = "C:\test"
$file = "music.mp3"
$saveOut = "saveout"
$jobScript =
{
#Start-Sleep -Seconds 20
Write-Output ('$outpath=' + $using:outpath + ' $file=' + $using:file + ' $saveOut=' + $using:saveOut)
}
$job = Start-Job -ScriptBlock $jobScript -ArgumentList outpath, file, saveout
Get-Job | Receive-Job
如果你想知道更多,那就跑吧Get-Help about_scopes
答案2
另请参阅本文,了解@jfrmilner 所暗示的良好解释。
了解如何实现 $Using:PowerShell 中对 PoshRSJob 的支持
但是,也可以考虑将所有参数放入哈希表中并传递该表。请参阅有关运行可执行文件的这篇文章。
例 5. 调用运算符 &
原因:用于将字符串视为单个命令。适用于处理空格。
在 PowerShell V2.0 中,如果您正在运行 7z.exe (7-Zip.exe) 或其他以数字开头的命令,则必须使用命令调用运算符 &。
PowerShell V3.0 解析器现在做得更智能了,在这种情况下您不再需要 & 。
详细信息:运行命令、脚本或脚本块。调用运算符也称为“调用运算符”,可让您运行存储在变量中并由字符串表示的命令。由于调用运算符不解析命令,因此它无法解释命令参数
& 'C:\Program Files\Windows Media Player\wmplayer.exe' "c:\videos\my home video.avi" /fullscreen
Things can get tricky when an external command has a lot of parameters or there are spaces in the arguments or paths! With spaces you have to nest Quotation marks and the result it is not always clear! In this case it is better to separate everything like so:
$CMD = 'SuperApp.exe'
$arg1 = 'filename1'
$arg2 = '-someswitch'
$arg3 = 'C:\documents and settings\user\desktop\some other file.txt'
$arg4 = '-yetanotherswitch'
& $CMD $arg1 $arg2 $arg3 $arg4
或者类似这样:
$AllArgs = @('filename1', '-someswitch', 'C:\documents and settings\user\desktop\some other file.txt', '-yetanotherswitch')
& 'SuperApp.exe' $AllArgs