private static ProcessFailedConditions GetMtnConditions()
        {
            ProcessFailedConditions mtnStat = new ProcessFailedConditions();

            // The input file is shorter than pre- and post-recording time
            mtnStat.AddCriticalOutString("net duration after -B & -E is negative");
            mtnStat.AddCriticalOutString("all rows're skipped?");
            mtnStat.AddCriticalOutString("step is zero; movie is too short?");
            mtnStat.AddCriticalOutString("failed: -");
            // unsupported video format by mtn.exe - maybe there's an update?
            mtnStat.AddCriticalOutString("couldn't find a decoder for codec_id");

            mtnStat.SuccessExitCode = 0;

            return(mtnStat);
        }
        private static bool StartProcess(string aAppName, string aArguments, string aWorkingDir, int aExpectedTimeoutMs,
                                         bool aLowerPriority, ProcessFailedConditions aFailConditions)
        {
            bool             success      = false;
            Process          ExternalProc = new Process();
            ProcessStartInfo ProcOptions  = new ProcessStartInfo(aAppName, aArguments);

            ProcOptions.UseShellExecute        = false; // Important for WorkingDirectory behaviour
            ProcOptions.RedirectStandardError  = true;  // .NET bug? Some stdout reader abort to early without that!
            ProcOptions.RedirectStandardOutput = true;  // The precious data we're after
            //ProcOptions.StandardOutputEncoding = Encoding.GetEncoding("ISO-8859-1"); // the output contains "Umlaute", etc.
            //ProcOptions.StandardErrorEncoding = Encoding.GetEncoding("ISO-8859-1");
            ProcOptions.WorkingDirectory = aWorkingDir; // set the dir because the binary might depend on cygwin.dll
            ProcOptions.CreateNoWindow   = true;        // Do not spawn a "Dos-Box"
            ProcOptions.ErrorDialog      = false;       // Do not open an error box on failure

            ExternalProc.OutputDataReceived += new DataReceivedEventHandler(OutputDataHandler);
            ExternalProc.ErrorDataReceived  += new DataReceivedEventHandler(ErrorDataHandler);
            ExternalProc.EnableRaisingEvents = true; // We want to know when and why the process died
            ExternalProc.StartInfo           = ProcOptions;
            if (File.Exists(ProcOptions.FileName))
            {
                try
                {
                    ExternalProc.Start();
                    if (aLowerPriority)
                    {
                        try
                        {
                            ExternalProc.PriorityClass = ProcessPriorityClass.BelowNormal;
                            // Execute all processes in the background so movies, etc stay fluent
                        }
                        catch (Exception ex2)
                        {
                            Log.Error("Util: Error setting process priority for {0}: {1}", aAppName, ex2.Message);
                        }
                    }
                    // Read in asynchronous  mode to avoid deadlocks (if error stream is full)
                    // http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandarderror.aspx
                    ExternalProc.BeginErrorReadLine();
                    ExternalProc.BeginOutputReadLine();

                    // wait this many seconds until the process has to be finished
                    ExternalProc.WaitForExit(aExpectedTimeoutMs);

                    success = (ExternalProc.HasExited && ExternalProc.ExitCode == aFailConditions.SuccessExitCode);

                    ExternalProc.OutputDataReceived -= new DataReceivedEventHandler(OutputDataHandler);
                    ExternalProc.ErrorDataReceived  -= new DataReceivedEventHandler(ErrorDataHandler);
                }
                catch (Exception ex)
                {
                    Log.Error("Util: Error executing {0}: {1}", aAppName, ex.Message);
                }
            }
            else
            {
                Log.Info("Util: Could not start {0} because it doesn't exist!", ProcOptions.FileName);
            }

            return(success);
        }
    private static bool StartProcess(string aAppName, string aArguments, string aWorkingDir, int aExpectedTimeoutMs,
                                     bool aLowerPriority, ProcessFailedConditions aFailConditions)
    {
      bool success = false;
      Process ExternalProc = new Process();
      ProcessStartInfo ProcOptions = new ProcessStartInfo(aAppName, aArguments);

      ProcOptions.UseShellExecute = false; // Important for WorkingDirectory behaviour
      ProcOptions.RedirectStandardError = true; // .NET bug? Some stdout reader abort to early without that!
      ProcOptions.RedirectStandardOutput = true; // The precious data we're after
      //ProcOptions.StandardOutputEncoding = Encoding.GetEncoding("ISO-8859-1"); // the output contains "Umlaute", etc.
      //ProcOptions.StandardErrorEncoding = Encoding.GetEncoding("ISO-8859-1");
      ProcOptions.WorkingDirectory = aWorkingDir; // set the dir because the binary might depend on cygwin.dll
      ProcOptions.CreateNoWindow = true; // Do not spawn a "Dos-Box"      
      ProcOptions.ErrorDialog = false; // Do not open an error box on failure        

      ExternalProc.OutputDataReceived += new DataReceivedEventHandler(OutputDataHandler);
      ExternalProc.ErrorDataReceived += new DataReceivedEventHandler(ErrorDataHandler);
      ExternalProc.EnableRaisingEvents = true; // We want to know when and why the process died        
      ExternalProc.StartInfo = ProcOptions;
      if (File.Exists(ProcOptions.FileName))
      {
        try
        {
          ExternalProc.Start();
          if (aLowerPriority)
          {
            try
            {
              ExternalProc.PriorityClass = ProcessPriorityClass.BelowNormal;
              // Execute all processes in the background so movies, etc stay fluent
            }
            catch (Exception ex2)
            {
              Log.Error("Util: Error setting process priority for {0}: {1}", aAppName, ex2.Message);
            }
          }
          // Read in asynchronous  mode to avoid deadlocks (if error stream is full)
          // http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandarderror.aspx
          ExternalProc.BeginErrorReadLine();
          ExternalProc.BeginOutputReadLine();

          // wait this many seconds until the process has to be finished
          ExternalProc.WaitForExit(aExpectedTimeoutMs);

          success = (ExternalProc.HasExited && ExternalProc.ExitCode == aFailConditions.SuccessExitCode);

          ExternalProc.OutputDataReceived -= new DataReceivedEventHandler(OutputDataHandler);
          ExternalProc.ErrorDataReceived -= new DataReceivedEventHandler(ErrorDataHandler);
        }
        catch (Exception ex)
        {
          Log.Error("Util: Error executing {0}: {1}", aAppName, ex.Message);
        }
      }
      else
        Log.Info("Util: Could not start {0} because it doesn't exist!", ProcOptions.FileName);

      return success;
    }
    private static ProcessFailedConditions GetMtnConditions()
    {
      ProcessFailedConditions mtnStat = new ProcessFailedConditions();
      // The input file is shorter than pre- and post-recording time
      mtnStat.AddCriticalOutString("net duration after -B & -E is negative");
      mtnStat.AddCriticalOutString("all rows're skipped?");
      mtnStat.AddCriticalOutString("step is zero; movie is too short?");
      mtnStat.AddCriticalOutString("failed: -");
      // unsupported video format by mtn.exe - maybe there's an update?
      mtnStat.AddCriticalOutString("couldn't find a decoder for codec_id");

      mtnStat.SuccessExitCode = 0;

      return mtnStat;
    }