Executing an external application....and getting its output (2 Viewers)

samuel337

Portal Pro
August 25, 2004
772
0
Melbourne, Australia
The MSDN example isn't what I was thinking of.

I was thinking of something along the lines of this:
- put all converting code in a seperate class. When you need to convert a file, instantiate that class, passing along the filename in its constructor. Give this class a class-scope variable, e.g. create a variable after the class declaration, not within a method.

e.g.
Code:
ConvertFile convertFileClass;

Here's an example class you can build on:
Code:
using System;
using System.Collections.Generic;
using System.Text;

namespace ProcessDemo
{
    public class ConvertFile
    {
        //enum to keep track of status
        private enum ConvertState
        {
            Step1 = 0, 
            Step2 = 1, 
            Step3 = 2,
            Finished = 3
        }
        
        //class variables
        System.Diagnostics.Process convertProcess;
        ConvertState curState;
        bool started;
        string BurnerFilesPath;
        string curFileName;
        string[] curFileNames;
        int curFileNameCount;
        string TempFolderPath;

        //constructor
        public ConvertFile(string[] FileNames)
        {
            curFileNames = FileNames;
            curFileNameCount = 0;
            NextFileName();
            started = false;
            BurnerFilesPath = "whatever here";
            TempFolderPath = "whatever here";
        }

        public void NextFileName()
        {
            curFileNameCount++;

            if (curFileNameCount <= curFileNames.Length)
            {
                //get next filename
                curFileName = curFileNames[curFileNameCount - 1];
                curState = ConvertState.Step1;

                //start again
                NextStep();
            }
            else
            {
                //all files processed
                AllFinished(this, new System.EventArgs());
            }
        }

        public bool Start()
        {
            if (started == false)
            {
                //start
                started = true;
                NextStep();
                return true;
            }
            else
            {
                return false;
            }
        }

        private void NextStep()
        {
            switch (curState)
            {
                case ConvertState.Step1:
                    //do stuff for step one here (e.g. transcoding from AVI to MPG)
                    //Example:
                    convertProcess = new System.Diagnostics.Process();
                    convertProcess.StartInfo.FileName = BurnerFilesPath + "mpgtx.exe";
                    convertProcess.StartInfo.Arguments = "-f -d \"" + curFileName + "\" -b \"" + TempFolderPath + "\\" + curFileName + "\" ";
                    convertProcess.EnableRaisingEvents = true; //IMPORTANT: tells process object to raise event when finished
                    convertProcess.Exited += new EventHandler(ProcessExitedHandler);
                    convertProcess.Start();
                    convertProcess.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(OutputDataReceivedHandler);
                    convertProcess.BeginOutputReadLine();
                    break;

                case ConvertState.Step2:
                    //do next step here, e.g. apply filters, do ad-removal etc.
                    break;

                case ConvertState.Step3:
                    //do last step here, e.g. burn to disc
                    break;

                case ConvertState.Finished:
                    //converting process completed, raise event
                    FileFinished(this, new FileFinishedEventArgs(curFileName));
                    NextFileName();
                    break;
            }
        }

        private void ProcessExitedHandler(object sender, System.EventArgs e)
        {
            //one process has finished, start next process
            curState += 1;
            NextStep();

            //announce to anyone who is listening
            CompletedStep(this, new System.EventArgs());
        }

        private void OutputDataReceivedHandler(object sender, System.Diagnostics.DataReceivedEventArgs e)
        {
            //announce to anyone who is listening
            OutputReceived(this, e);
        }

        //events
        //in your UI class, listen in on these events to report back to user
        public event EventHandler CompletedStep;

        public delegate void FileFinishedEventHandler(object sender, FileFinishedEventArgs e);
        public event FileFinishedEventHandler FileFinished;

        public event EventHandler AllFinished;
        public event System.Diagnostics.DataReceivedEventHandler OutputReceived;
    }

    public class FileFinishedEventArgs : System.EventArgs
    {
        public string FileName;

        public FileFinishedEventArgs(string FinishedFileName)
        {
            FileName = FinishedFileName;
        }
    }
}

When you need to use this class in your UI, do this:
Code:
private void ConvertFiles()
{
convertFileClass = new ConvertFile(FilesToBurn);
convertFileClass.CompletedStep += new EventHandler(convertCompletedStep);
convertFileClass.FileFinished+= new FileFinishedEventHandler(convertFileFinished);
convertFileClass.AllFinished+= new EventHandler(convertAllFinished);
convertFileClass.OutputReceived+= new System.Diagnostics.DataReceivedEventHandler(convertOutputReceived);

convertFileClass.Start();
}

You will need to create methods, convertCompletedStep, convertFileFinished, convertAllFinished, convertOutputReceived to handle the events raised by the ConvertFile class.

This code is untested, so there may be small problems with it, but it should work.

HTH

Sam
 

mbuzina

Retired Team Member
  • Premium Supporter
  • April 11, 2005
    2,839
    726
    Germany
    Home Country
    Germany Germany
    egonspengleruk said:
    I think I have sorted out how to capture the output of an executed file....but how do I run several apps one after each other?

    E.g. I want to run Command1.exe and capture its output, when its finished successfully then run Command2.ex and captures its output............etc

    Egon

    To find out when the called program has finished, you may use the Exited Event on the Process Object or use the WaitForExit Method (as in the code above). When you know that the first process is done (and maybe the result was acceptable, e.g. no errors) you may call the 2nd prog exactly the same way.

    If you have 2 uses for the output of the program (e.g. one for showing the user and one for checking correctness or errors) you should consider using 2 delegates on the OutputDataReceived, one for each task. The more desktops are multi-processor environments, the more parallel we developers have to think.
     

    Users who are viewing this thread

    Top Bottom