How to show the output of a *.bat or *.cmd file in a WPF application, without waiting for the *.bat file to end

How to show the output of a *.bat or *.cmd file in a WPF application, without waiting for the *.bat file to end

Notes

  • The functions
    – process.StandardOutput.ReadToEnd();
    – process.StandardOutput.Read();
    – process.StandardOutput.ReadLine();
    will wait for the process to end and then output the result.
  • If you want to show the output during processing, you should use
    – process.OutputDataReceived += new DataReceivedEventHandler(ProcessOuputHandler);
    – and process.BeginOutputReadLine();
  • Because the BeginOutputReadLine will spawn a new thread, you can’t access the UI directly. If you want to update a textbox, you should use the control.Dispatcher.Invoke function.
  • With the control.Dispatcher.CheckAccess() you can determine if the functions is called from the UI thread or not.
  • [myWpfWindow] is a WPF window containing a textbox with the name [outputTextBox] and a button with the name [testButton].
  • The function [ShowingOutputOfBatFile] is called from a [testButton] click eventhandler
public void ShowingOutputOfBatFile()
{
    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.FileName = @"C:\Temp\Test.bat";
    startInfo.Arguments = "firstParameter secondParamter";
    startInfo.RedirectStandardError = true;
    startInfo.RedirectStandardOutput = true;
    startInfo.UseShellExecute = false;
    startInfo.WorkingDirectory = @"C:\Temp";
    // Use startInfo.CreateNoWindow = HideWindow; if you want to hide the window
    using (Process process = new Process())
    {
        process.StartInfo = startInfo;
        process.OutputDataReceived += new DataReceivedEventHandler(ProcessOuputHandler);
        process.Start();
        process.BeginOutputReadLine();
        while (!process.HasExited)
        {
            // Refresh you're WPF window here
            myWpfWindow.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
            Thread.Sleep(1000);
        }
    }
}
public void ProcessOuputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
    if (!String.IsNullOrEmpty(outLine.Data))
    {
        if (!outputTextBox.Dispatcher.CheckAccess())
        {
            // Called from a none ui thread, so use dispatcher
            ShowLoggingDelegate showLoggingDelegate = new ShowLoggingDelegate(ShowLogging);
            outputTextBox.Dispatcher.Invoke(DispatcherPriority.Normal, showLoggingDelegate, outLine.Data);
        }
        else
        {
            // Called from UI trhead so just update the textbox
            ShowLogging(outLine.Data);
        };
    }
}
private delegate void ShowLoggingDelegate(string text);
private static Action EmptyDelegate = delegate () { };
/// <summary>
/// Show the logging on screen
/// </summary>
/// <param name="text"></param>
private void ShowLogging(string text)
{
    myWpfWindow.outputTextBox.AppendText(text);
    myWpfWindow.outputTextBox.ScrollToEnd();
}

How to show the output of a *.bat or *.cmd file in a WPF application, without waiting for the *.bat file to end

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注