System.Diagnostics.Process程序继续运行

本文关键字:继续 运行 程序 Process Diagnostics System | 更新日期: 2023-09-27 18:22:18

我正试图使用命令行应用程序中的ffmpeg库将一些avi文件转换为mkv。我做了一个可以做到这一点的方法:

public bool convertAvitoMkv(string path, string sourceName, string destName)
    {
        bool returncode = false;
        try
        {
            string comando = string.Format("-i {0} -c:v libx264 -crf 19 -preset slow -c:a libfaac -b:a 192k -ac 2 {1}", string.Format("{0}''{1}",path,sourceName), string.Format("{0}''{1}",path,destName) + ".mkv");
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            startInfo.FileName = "ffmpeg.exe";
            startInfo.WorkingDirectory = programPath;
            startInfo.CreateNoWindow = true;
            startInfo.Arguments = comando;
            process.StartInfo = startInfo;
            process.Start();
            while (!process.HasExited)
            {
                process.Kill(); 
                //continue hasta que termine la ejecucion
            }
            returncode = process.HasExited;
        }
        catch (Exception ex)
        {
        }
        return returncode;
    }

以前的版本没有while(!process.HasExited),但我添加了它,因为我注意到有很多ffmpeg.exe的实例在运行,我不得不手动关闭。我如何保证每一个conversión都已完成,ffmpeg的每一个实例都已关闭?关于

System.Diagnostics.Process程序继续运行

public bool concatenarArchivos(string archivos, string path, string destName)
    {
        bool returncode = false;
        try
        {
            string[] extensions = {".mp4"};
            string[] dirContents = System.IO.Directory.GetFiles(path, "*.*").Where(f => extensions.Contains(new FileInfo(f).Extension.ToLower())).ToArray();
            if (dirContents.Length > 0)
            {
                string comando = string.Format("-f concat -i {0} -c copy {1}", archivos, string.Format("{0}''{1}", path, destName));
                System.Diagnostics.Process process = new System.Diagnostics.Process();
                System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
                startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                startInfo.FileName = "ffmpeg.exe";
                startInfo.WorkingDirectory = programPath;
                startInfo.CreateNoWindow = true;
                startInfo.Arguments = comando;
                process.StartInfo = startInfo;
                process.Start();
                process.WaitForExit();
                //process.Close();
                process.Dispose();
                //returncode = process.HasExited;
            }
        }
        catch (Exception ex)
        {
        }
        return returncode;
    }

我遇到了同样的问题。在调试时,我注意到当我使用WaitForExit时,它一直在无限期地等待。当我将while循环与!process.HasExited一起使用时,它也没有通过while循环。

一旦我添加了标准输出和错误的重定向,并读取了流,它就开始像预期的那样工作。

似乎当出现某种输出(常规和/或错误)时,进程会一直等待,直到输出得到处理。之前它不会退出。

按照以下方式更改代码很可能会解决您的问题。

public bool convertAvitoMkv(string path, string sourceName, string destName)
    {
        bool returncode = false;
        try
        {
            string comando = string.Format("-i {0} -c:v libx264 -crf 19 -preset slow -c:a libfaac -b:a 192k -ac 2 {1}", string.Format("{0}''{1}",path,sourceName), string.Format("{0}''{1}",path,destName) + ".mkv");
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            startInfo.FileName = "ffmpeg.exe";
            startInfo.WorkingDirectory = programPath;
            startInfo.CreateNoWindow = true;
            startInfo.Arguments = comando;
            startInfo.RedirectStandardOutput = true;
            startInfo.RedirectStandardError = true;
            process.StartInfo = startInfo;
            process.Start();
            StreamReader readerOut = process.StandardOutput;
            StreamReader readerErr = process.StandardError;
            // Process the readers e.g. like follows
            string errors = readerErr.ReadToEnd();
            string output = readerOut.ReadToEnd();
            while (!process.HasExited)
            {
                continue; 
            }
            returncode = process.HasExited;
        }
        catch (Exception ex)
        {
        }
        return returncode;
    }