I'm writing a program that reads cmd script output and shows the results in a log (View Model). Since the script running for a long time, I want to be able to see the output after each line is written. Now I can see the output only when the process ends. I have no idea how to do it în Wpf-MVVM.
StepViewModel
public StepsViewModel()
{
RunSteps = new RelayCommand(OnRunSteps);
Steps = new ObservableCollection<Step>();
AddSteps();
}
private void OnRunSteps(object obj)
{
IsEnabled = false;
foreach (var step in Steps)
{
if (step.IsChecked)
StepsManager.Instance.RunStep(step);
}
IsEnabled = true;
}
StepsManager
public void RunStep(Step step)
{
switch (step.Name)
{
case "MyStep":
MyStep(0); // 0 is the index of the step
break;
}
}
private void MyStep(int stepIndex)
{
VMLocator.LogsViewModel.Logs.Add(new Log("MyStep", false)); // fale -> green colore, red -> red color
;
string command = @"mycmd";
ExecuteCmd(command);
}
private void ExecuteCmd(string command)
{
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command)
{
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
// The following commands are needed to redirect the standard output.
// This means that it will be redirected to the Process.StandardOutput StreamReader.
// Do not create the black window.
System.Diagnostics.Process
proc = new System.Diagnostics.Process
{
StartInfo = procStartInfo
}; // Now we create a process, assign its ProcessStartInfo and start it
proc.Start();
List<string> outputData = new List<string>();
List<string> errorData = new List<string>();
proc.OutputDataReceived += (s, e) =>
{
lock (outputData)
{
if (!string.IsNullOrEmpty(e.Data))
{
outputData.Add(e.Data);
UpdateLog(e.Data, stepIndex);
}
}
};
proc.ErrorDataReceived += (s, e) =>
{
lock (errorData)
{
if (!string.IsNullOrEmpty(e.Data))
{
errorData.Add(e.Data);
UpdateLog(e.Data, stepIndex);
}
}
};
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
proc.WaitForExit();
}
private void UpdateLog(string log)
{
if(few checks for log)
VMLocator.LogsViewModel.Logs.Add(new Log(log, false)); // fale -> green colore, red -> red color
}
LogViewModel
public ObservableCollection<Log> Logs { get; set; }
#endregion
public LogsViewModel()
{
Logs = new RelayCommand.AsyncObservableCollection<Log>();
}
Log
public string Message { get; set; }
public string Color { get; set; }
public Log(string message, bool error)
{
Message = message;
Color = error ? "Red" : "Green";
}
public Log(string message, string color)
{
Message = message;
Color = color;
}