简体   繁体   中英

How to handle a multi-line message with process.OutputDataReceived?

I have written code that receives data from a process and handles it in OutputDataReceived . It doesn't work when a multiline message is received. Each line causes a separate invocation of OutputDataReceived , and then the startSequence and endSequence are not found within the same message, causing no match.

What is a good way to solve this?

process.OutputDataReceived += (object sender, DataReceivedEventArgs e) =>
{
  if (!String.IsNullOrEmpty(e.Data))
  {
    err = OnOutputDataReceived(e.Data);
  }
};

private string OnOutputDataReceived(string data)
{
  string startSeq = "|-->";
  string delimiterSeq = "<-->";
  string endSeq = "<--|";
  string pattern = @"\|-->.*?<\--\|";
  RegexOptions options = RegexOptions.Singleline;
  Match match = Regex.Match(data, pattern, options);

  while (match.Success)
  {
    string trimmedValue = match.Value.Replace(startSeq, "").Replace(endSeq, "");
    string[] messageParts = trimmedValue.Split(new string[] { delimiterSeq }, System.StringSplitOptions.None);
    int minValidMessageParts = 3;
    Console.WriteLine(messageParts);
    if (messageParts.Length >= minValidMessageParts)
    {
      string messageType = messageParts[1];

      if (messageType == "Progress")
      {
        string incrementStr = messageParts[3];
        int.TryParse(incrementStr, out int increment);
        OnProgressCallback(this, new ProgressCallbackEventArgs(increment));
      }
      else if (messageType == "Fatal")
      {
        string messageText = messageParts[2];
        return String.Format("Conversion failed: {0}", messageText);
      }
    }

    match = match.NextMatch();
  }

  return null;
}

You can try something like this:

StringBuilder output = new StringBuilder();
process.OutputDataReceived += (object sender, DataReceivedEventArgs e) =>
{
  if (!String.IsNullOrEmpty(e.Data))
  {
    output.Add(e.Data);
    err = OnOutputDataReceived(output.ToString());
  }
};

Although this may be a bit heavy handed - as it scans whole output anytime one line is added... You should be able to easily limit based on your requirements though, ie only pass last X lines or whatever you require?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM