question

mionshion-3520 avatar image
0 Votes"
mionshion-3520 asked karenpayneoregon commented

c# fourms get live output from cmd line by line

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
dotnet-csharpdotnet-cli
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

As best as I understand your question, my sample does what you need.

0 Votes 0 ·
karenpayneoregon avatar image
0 Votes"
karenpayneoregon answered karenpayneoregon commented

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);
     }
 }




f1.png (30.6 KiB)
· 7
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

hey thanks for reply this is exactly what i want however using visual studio 2019 and framwork 4.8.1

and i am getting the following error when trying to implement this,

Severity Code Description Project File Line Suppression State

Error CS8370 Feature 'using declarations' is not available in C# 7.3. Please use language version 8.0 or greater. UpdateTest G:\Backup_151022_windows_11\Desktop\Restore_Repoll Program\Project_Kaori\meh\TutUpdater\UpdateTest\SpotDL.cs 83 Active

is there a way to upgrade to this version on .net frame work ?





0 Votes 0 ·

See the section Edit under the image, see if that works in .NET Framework 4.8.1

0 Votes 0 ·

yeah i have that part of code working fine now thank you :) issue i have now is the ANSI console line

AnsiConsole.MarkupLine("[yellow]Hello[/]");

Severity Code Description Project File Line Suppression State
Error CS0103 The name 'AnsiConsole' does not exist in the current context UpdateTest C:\Users\elfenliedtopfan5\Desktop\Project_Kaori\TutUpdater\UpdateTest\Form1.cs 156 Active


not quite sure if this is a namespace i am missing or what but cant seem to find any ref to it anywhere.

0 Votes 0 ·
Show more comments

Yep i have done that however i am calling this from button call - on windows forms that i can do private async but cant make it task or it will break so have the following,

                     private async void simpleButton3_Click(object sender, EventArgs e)
     {
         //AnsiConsole.MarkupLine("[yellow]Hello[/]");
         var (success, details, localException) = await elfenspot.Execute(@"c:\test");
         if (success)
         {
             elftext(details);
         }
         else if (localException != null)
         {
             elftext(localException.Message);
         }
         Console.ReadLine();
     }
0 Votes 0 ·
Show more comments
SimpleSamples avatar image
0 Votes"
SimpleSamples answered

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}");
 }




5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.