Passing void(object, DataReceivedEventArgs) to function

472 views Asked by At

I'm writing a function which creates a Process and runs it.

Here is the original function:

public static void LaunchApplication(string runCommand, string commandArguments, string workingDir, string informMessage)
{
    try
    {
        Process applicationProcess = new Process();
        applicationProcess.StartInfo.FileName = runCommand;
        applicationProcess.StartInfo.WorkingDirectory = workingDir;
        applicationProcess.StartInfo.Arguments = commandArguments;
        applicationProcess.StartInfo.UseShellExecute = false;

        WriteHeadlineToConsole(informMessage);

        applicationProcess.Start();
        while (Process.GetProcesses().Any(runningProcess => runningProcess.Id == applicationProcess.Id)) { }

        WriteHeadlineToConsole("Finished " + informMessage);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        return;
    }
}

I would like to change the functions' signature to something like:

public static void LaunchApplication(string runCommand, string commandArguments, string workingDir, string informMessage, Func<object, DataReceivedEventArgs> myMethodName)

And then inside the function, redirect the output, something like:

applicationProcess.OutputDataReceived += new DataReceivedEventHandler(myMethodName);

Can this be done?

1

There are 1 answers

2
Tony On BEST ANSWER

Try this:

public static void LaunchApplication(string runCommand, string commandArguments, string workingDir, string informMessage, Action<string> redirectOutput, Action<string> redirectError)
{
    try
    {
        Process applicationProcess = new Process();
        applicationProcess.StartInfo.FileName = runCommand;
        applicationProcess.StartInfo.WorkingDirectory = workingDir;
        applicationProcess.StartInfo.Arguments = commandArguments;
        applicationProcess.StartInfo.UseShellExecute = false;
        applicationProcess.EnableRaisingEvents = true;
        applicationProcess.StartInfo.CreateNoWindow = true;

        if (redirectOutput != null)
            applicationProcess.OutputDataReceived += (s, data) => redirectOutput(data.Data);

        if (redirectError != null)
            applicationProcess.ErrorDataReceived += (sErr, errData) => redirectError(errData.Data);

        GeneralUtils.WriteHeadlineToConsole(informMessage);
        applicationProcess.Start();
        if (redirectOutput != null)
            applicationProcess.BeginOutputReadLine();
        if (redirectError != null)
            applicationProcess.BeginErrorReadLine();
        applicationProcess.WaitForExit();
        GeneralUtils.WriteHeadlineToConsole("Finished " + informMessage);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        return;
    }
}

Usage:

LaunchApplication("cmd.exe", "/C ipconfig /all", "C:\\Windows", "Test", 
            s => Console.WriteLine("HELLO: " + s));

PS: The following code is awful! AccessDeniedException might be thrown, CPU is going crazy!

while (Process.GetProcesses().Any(runningProcess => runningProcess.Id == applicationProcess.Id)) { }

Use applicationProcess.WaitForExit(); instead!