c# fourms get live output from cmd line by line

mion shion 241 Reputation points
2022-10-27T22:24:23.377+00:00

good evening all,

i have been working on getting output from cmd

however, i was wondering if there was a way to get output from cmd one line at a time

instead of it doing all the lines in one and reporting all at once.

System.Diagnostics.Process p = new System.Diagnostics.Process();

p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = "cmd.exe";
path = @"C:\test";
if(path == string.Empty)
{
string[] myargs = {example arguments};
string elfen = string.Join("", myargs);
XtraMessageBox.Show(elfen);
p.StartInfo.Arguments = string.Join("", elfen);
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.Start();

StreamReader outputWriter2 = p.StandardOutput;
//String errorReader = p.StandardError.ReadToEnd();
String line2 = outputWriter2.ReadLine();
while (line2 != null)
{
line2 = outputWriter2.ReadLine(); // ADDED
if (line2 != null)
{
splitstrings(line2);
}

}
p.WaitForExit();
}

but it gets to - StreamReader outputWriter2 = p.StandardOutput;
to here and waits for the process to report all

because at the moment it will wait for the process to end and then report it,
when i want it to report line then line

is this possible

thank you in advance
elfenliedtopfan5

.NET CLI
.NET CLI
A cross-platform toolchain for developing, building, running, and publishing .NET applications.
325 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,527 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Karen Payne MVP 35,286 Reputation points
    2022-10-27T23:33:09.253+00:00

    Here is an example

    using System.Diagnostics;  
    using System.Text;  
      
    namespace DotNetRunTimeProcessStartApp.Classes;  
      
    internal class Operations  
    {  
        public static async Task<(bool succcess, string, Exception localException)> Execute()  
        {  
            try  
            {  
      
                var start = new ProcessStartInfo  
                {  
                    FileName = "powershell.exe",  
                    RedirectStandardOutput = true,  
                    Arguments = "dotnet --list-runtimes",  
                    CreateNoWindow = true  
                };  
      
                using var process = Process.Start(start);  
                using var reader = process!.StandardOutput;  
      
                process.EnableRaisingEvents = true;  
      
                var lineData = await reader.ReadToEndAsync();  
                var items = lineData.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);  
      
                StringBuilder builder = new();  
                foreach (var item in items)  
                {  
                    if (item.Contains("["))  
                    {  
                        builder.AppendLine("   " + item.Substring(0, item.IndexOf("[", StringComparison.Ordinal) - 1));  
                    }  
                }  
      
                return (true, builder.ToString(), null)!;  
            }  
            catch (Exception localException)  
            {  
      
                return (false, "Failed", localException);  
            }  
        }  
    }  
    

    Usage

    internal partial class Program  
    {  
        static async Task Main(string[] args)  
        {  
            AnsiConsole.MarkupLine("[yellow]Hello[/]");  
            var (success, details, localException) = await Operations.Execute();  
            if (success)  
            {  
                Console.WriteLine(details);  
            }  
            else if (localException is not null)  
            {  
                Console.WriteLine(localException.Message);  
            }  
            Console.ReadLine();  
        }  
    }  
    

    254916-f1.png

    Edit

    internal class Operations  
    {  
    public static async Task<(bool succcess, string, Exception localException)> Execute()  
    {  
        try  
        {  
      
            var start = new ProcessStartInfo  
            {  
                FileName = "powershell.exe",  
                RedirectStandardOutput = true,  
                Arguments = "dotnet --list-runtimes",  
                CreateNoWindow = true  
            };  
      
      
            using (var process = Process.Start(start))  
            {  
                var reader = process!.StandardOutput;  
      
                process.EnableRaisingEvents = true;  
      
                var lineData = await reader.ReadToEndAsync();  
                var items = lineData.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);  
      
                StringBuilder builder = new();  
                foreach (var item in items)  
                {  
                    if (item.Contains("["))  
                    {  
                        builder.AppendLine("   " + item.Substring(0, item.IndexOf("[", StringComparison.Ordinal) - 1));  
                    }  
                }  
      
                return (true, builder.ToString(), null)!;  
            }  
              
        }  
        catch (Exception localException)  
        {  
      
            return (false, "Failed", localException);  
        }  
    }  
    

  2. Sam of Simple Samples 5,521 Reputation points
    2022-10-28T02:44:14.607+00:00

    Are you sure you need to use cmd.exe? Probably not. You need it only if you are executing a command that is internal to the command shell, such as dir. Or a batch file.

    See Process.OutputDataReceived Event. The following is a simplified version of what you are doing but should show a way to do it. It works for me.

    static void Main(string[] args)  
    {  
        Process p = new System.Diagnostics.Process();  
        p.StartInfo.UseShellExecute = false;  
        p.StartInfo.FileName = "entire path to exe";  
        p.StartInfo.Arguments = "argone argtwo";  
        p.StartInfo.RedirectStandardOutput = true;  
        p.OutputDataReceived += LiveOutputHandler;  
        p.Start();  
        p.BeginOutputReadLine();  
        p.WaitForExit();  
    }  
      
    private static void LiveOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)  
    {  
        Console.WriteLine($"Received: {outLine.Data}");  
    }  
    
    0 comments No comments