如何在Process.Start中使用两个进程之间的管道



我必须使用VB运行这个命令行。净:

" H: videotest 测试。vpy" - -y | "H:Releasedatabin64ffmpeg.exe" -hwaccel auto -y -i - -map 0:v:0 -c:v libx265 -crf 20.0 -preset 5- x265-params水平= 0:概要=定义:pmode: no-pme:中外:no-high-tier: ref = 3: bframes = 4: open-gop: keyint = 250: min-keyint = 25: b-adapt = 2: bframe-bias = 0: rc-lookahead = 20: no-scenecut: b-pyramid:我=十六进制:subme = 2: merange = 57: temporal-mvp: weightp: no-weightb: max-merge = 2: no-weightb: no-rect: no-amp: vbv-bufsize = 0: vbv-maxrate = 0: vbv-init = 0.9: no-strict-cbr: qcomp = 0.6: qstep = 4: aq-mode = 1: aq-strength = 1.0: cutree: no-early-skip: min-cu-size = 8:反恐组= 64:no-fast-cfb: ipratio = 1.4: pbratio = 1.3: cbqpoffs = 0: crqpoffs = 0: rd = 3: psy-rd = 0.3: psy-rdoq = 1: no-b-intra: no-fast-intra: rdoq-level = 1: no-tskip: no-tskip-fast: cu-lossless: tu-intra-depth = 1: tu-inter-depth = 1: strong-intra-smoothing: no-constrained-intra: nr-intra = 0: nr-inter = 0: qblur = 0.5: cplxblur = 20: signhide: sar = 16"H: videotest outputawdwd.mkv "

vspipe.exe运行test.vpy脚本并对视频输入应用过滤器或调整大小,然后输出管道到ffmpeg进行编码。

如果我使用vspipe的正常进程声明,它给出以下错误:

未知参数:|

在命令行中,脚本运行良好。我怀疑这意味着我必须手动在vspipeffmpeg之间进行管道连接。

是否可以手动将输出从一个进程管道到另一个进程?我必须手动操作吗?

下面是我启动进程的函数:

executablepath = "H:ProjectVapourSynthcore64vspipe.exe"
params = "H:videotesttest.vpy" - -y | "H:Releasedatabin64ffmpeg.exe" -hwaccel auto -y -i - -map 0:v:0 -c:v libx265 -crf 20.0 -preset 5 -x265-params level=0:profile=undefined:pmode:no-pme:pme:no-high-tier:ref=3:bframes=4:open-gop:keyint=250:min-keyint=25:b-adapt=2:bframe-bias=0:rc-lookahead=20:no-scenecut:b-pyramid:me=hex:subme=2:merange=57:temporal-mvp:weightp:no-weightb:max-merge=2:no-weightb:no-rect:no-amp:vbv-bufsize=0:vbv-maxrate=0:vbv-init=0.9:no-strict-cbr:qcomp=0.6:qstep=4:aq-mode=1:aq-strength=1.0:cutree:no-early-skip:min-cu-size=8:ctu=64:no-fast-cfb:ipratio=1.4:pbratio=1.3:cbqpoffs=0:crqpoffs=0:rd=3:psy-rd=0.3:psy-rdoq=1:no-b-intra:no-fast-intra:rdoq-level=1:no-tskip:no-tskip-fast:cu-lossless:tu-intra-depth=1:tu-inter-depth=1:strong-intra-smoothing:no-constrained-intra:nr-intra=0:nr-inter=0:qblur=0.5:cplxblur=20:signhide:sar=16 "H:videotestoutputawdwd.mkv"
Private Sub CreateJobProcess(ByVal Name, ByVal executablepath, ByVal params)
    Try
        If Not jobs_processes.ContainsKey(Name) Then
            Dim Proc As New Process
            Proc.StartInfo.UseShellExecute = False
            Proc.StartInfo.CreateNoWindow = True
            Proc.StartInfo.RedirectStandardError = True
            Proc.StartInfo.FileName = "" & executablepath & ""
            Proc.StartInfo.Arguments = params
            'start process
            Proc.Start()
            'add new process to dictionary
            jobs_processes.Add(Name, Proc)
            'TEMP
            My.Settings.giobbe -= 1
            'start background workers for statistics
            If Not ConversionStats.IsBusy Then
                ConversionStats.WorkerSupportsCancellation = True
                ConversionStats.RunWorkerAsync()
            End If
            If Not UpdateListJob.IsBusy Then
                UpdateListJob.WorkerSupportsCancellation = True
                UpdateListJob.RunWorkerAsync()
            End If
        End If
    Catch ex As Exception
        Me.Invoke(New MethodInvoker(Sub() Logbox.AppendText(Environment.NewLine & ">Program exception:" & Environment.NewLine & ex.Message & Environment.NewLine)))
        MsgBox(ex.Message)
    End Try
End Sub

更新:

这是我已经更改的块,该函数获取需要创建的作业的名称和参数,然后将进程保存在字典中。

              Dim Proc As New Process
                Proc.StartInfo.UseShellExecute = False
                Proc.StartInfo.CreateNoWindow = True
                Proc.StartInfo.RedirectStandardError = True
                Proc.StartInfo.FileName = "cmd"
                Proc.StartInfo.Arguments = params
                'start process
                Proc.Start()
                'add new process to dictionary
                jobs_processes.Add(Name, Proc)
                'TEMP
                My.Settings.giobbe -= 1
                'start background workers for statistics
                If Not ConversionStats.IsBusy Then
                    ConversionStats.WorkerSupportsCancellation = True
                    ConversionStats.RunWorkerAsync()
                End If
                If Not UpdateListJob.IsBusy Then
                    UpdateListJob.WorkerSupportsCancellation = True
                    UpdateListJob.RunWorkerAsync()
                End If

然后我有一个后台工作者(converversionstats),从字典中的每个进程中获取stderr,并将它们打印到文本框中:

           'take current selected process and set streamreader
            Dim tmpproc As Process = jobs_processes(CurrentJob)
            Dim ffmpeg_stats As StreamReader
            Dim stdoutput As String = ""
            'something that verify if the job is started 
            If statejob = 1 Then    'if job is working
                'take stderr from ffmpeg
                ffmpeg_stats = tmpproc.StandardError
                stdoutput = ffmpeg_stats.ReadLine()
                If stdoutput IsNot Nothing Then 'if ffmpeg stderr is not nothing 
                    'IF FFMPEG IS RETURNING STATS
                    If stdoutput.Contains("frame=") Or stdoutput.Contains("size=") Then

这是我的代码…但现在与cmd获得标准错误与流阅读器导致一个字符串"无效句柄。"这是一个错误从cmd stderr或有一个问题与流阅读器?

更新2

我甚至尝试过启动一个干净的cmd进程,只声明参数,但结果只是控制台的主要信息。

Microsoft Windows [version 6.3.9600]2013年微软公司。图蒂i diritti riservati。

项目

H: bin 释放>

这是要澄清的代码:

                Dim Proc As New Process
                Proc.StartInfo.FileName = "cmd"
                Proc.StartInfo.Arguments = params
                'start process
                Proc.Start()

所以再次有人可以指导我如何管道/重定向标准输出从一个进程(vspipe.exe)到另一个进程(ffmpeg.exe)的标准输入?

既然您知道命令字符串在命令行上工作,那么最简单的方法就是让cmd.exe为您运行代码。正如Plutonix在他的评论中所建议的,在这个回答中,Mark提供了一个如何在c#代码中做到这一点的示例。

Process test = new Process();
test.StartInfo.FileName = "cmd";
test.StartInfo.Arguments = @"/C ""echo testing | grep test""";
test.Start();

适应你的目的,翻译成VB.net可能看起来像这样(使用你在代码中声明的相同变量):

Dim Proc As New Process()
Proc.StartInfo.FileName = "cmd"
Proc.StartInfo.Arguments = "/C """ & executablepath & " " & params & """
Proc.Start()

这和你以前做的有什么不同?您使用Process.Start运行vspipe.exe,然后将params传递给它。上面的新代码使用Process.Start代替cmd.exe,打开命令提示符窗口,并输入完整的命令行字符串。

接收stdoutstderr需要两个步骤。首先,您必须将每个的'redirect'属性设置为True,然后在启动该进程后,手动检索所需的输出。

Dim Proc As New Process()
Proc.StartInfo.FileName = "cmd"
Proc.StartInfo.Arguments = executablepath & " " & params
'Capture stdio & stderr:
Proc.StartInfo.RedirectStandardOutput = True
Proc.StartInfo.RedirectStandardError = True
Proc.Start()
'Read stdio & stderr:
Dim StdIO As String = Proc.StandardOutput.ReadToEnd()
Dim StdErr As String = Proc.StandardError.ReadToEnd()
    <
  • RedirectStandardOutput属性/gh><
  • RedirectStandardError属性/gh>

RE: UPDATE 2:

这个特殊情况下的问题是Arguments字符串是一堆必须转义的双引号。在vb.net中,这是通过双双引号("")完成的,如果它们位于字符串的开头或结尾,则可以显示为"三双引号"("""),如果有许多需要转义的双引号,则可以显示为更长的双引号倍数。

虽然我的系统上没有必要的特定软件来测试,但以下应该可以工作:

Dim Proc As New Process
Proc.StartInfo.CreateNoWindow = True
Proc.StartInfo.UseShellExecute = False
Proc.StartInfo.FileName = "cmd"
Proc.StartInfo.Arguments = "/C ""H:ProjectVapourSynthcore64vspipe.exe ""H:videotesttest.vpy"" - -y | ""H:Releasedatabin64ffmpeg.exe"" -hwaccel auto -y -i - -map 0:v:0 -c:v libx265 -crf 20.0 -preset 5 -x265-params level=0:profile=undefined:pmode:no-pme:pme:no-high-tier:ref=3:bframes=4:open-gop:keyint=250:min-keyint=25:b-adapt=2:bframe-bias=0:rc-lookahead=20:no-scenecut:b-pyramid:me=hex:subme=2:merange=57:temporal-mvp:weightp:no-weightb:max-merge=2:no-weightb:no-rect:no-amp:vbv-bufsize=0:vbv-maxrate=0:vbv-init=0.9:no-strict-cbr:qcomp=0.6:qstep=4:aq-mode=1:aq-strength=1.0:cutree:no-early-skip:min-cu-size=8:ctu=64:no-fast-cfb:ipratio=1.4:pbratio=1.3:cbqpoffs=0:crqpoffs=0:rd=3:psy-rd=0.3:psy-rdoq=1:no-b-intra:no-fast-intra:rdoq-level=1:no-tskip:no-tskip-fast:cu-lossless:tu-intra-depth=1:tu-inter-depth=1:strong-intra-smoothing:no-constrained-intra:nr-intra=0:nr-inter=0:qblur=0.5:cplxblur=20:signhide:sar=16 ""H:videotestoutputawdwd.mkv"""
Proc.StartInfo.RedirectStandardOutput = True
Proc.StartInfo.RedirectStandardError = True
Proc.Start()
Dim so As String = Proc.StandardOutput.ReadToEnd
Dim se As String = Proc.StandardError.ReadToEnd
Proc.WaitForExit()

相关内容

  • 没有找到相关文章

最新更新