2016-09-02 3 views
2

Я создал консольное приложение с использованием C#, и я вызвал его из другого приложения Windows Forms, используя Process.Обработка ошибок с использованием процесса C#

Ниже приведен код для консольного приложения

static void Main(string[] args) 
     { 
      try 
      { 
       // ...my code 
      } 
      catch (Exception) 
      { 

       throw; 
      } 
     } 

Ниже код для вызова ехе приложения консоли из окна приложения с помощью процесса

public void CallExe() 
    { 
     try 
     {        
      Process proc = new Process(); 
      proc.StartInfo.FileName = @"D:\Debug\console1.exe"; 
      proc.StartInfo.Arguments = "My args"; 
      proc.StartInfo.CreateNoWindow = true; 
      proc.StartInfo.RedirectStandardError = true; 
      proc.StartInfo.RedirectStandardOutput = true; 
      proc.StartInfo.UseShellExecute = false; 
      proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
      proc.Start();    
      proc.WaitForExit();    
      string stdout = proc.StandardOutput.ReadToEnd(); 
      string stderr = proc.StandardError.ReadToEnd(); 
      proc = null; 
     } 

     catch (Exception ex) 
     { 

      throw ex; 
     } 
    } 

Теперь, что я хочу, когда какая-либо ошибка поступает из консольного приложения , он напрямую бросает в мой блок захвата окна. Или я могу получить сообщение об ошибке в моем оконном приложении, которое создается консольным приложением?

+1

вы не может поймать ошибку, которая возникает в другом процессе, но вы _can_ возвращаете код выхода из консольного приложения. – stuartd

+0

Могу ли я получить ex.message из консольного приложения? –

+1

Вы можете [указать код выхода] (http://stackoverflow.com/questions/155610/how-do-i-pecpec-the-exit-code-of-a-console-application-in-net), который целое число и выберите его из ['Process.ExitCode'] (https://msdn.microsoft.com/en-us/library/system.diagnostics.process.exitcode (v = vs.110) .aspx). Или вы можете читать/писать все, что хотите, от/до StandardOutput или StandardError – stuartd

ответ

1

Вы не захватываете ничего из процесса, который вы запускаете. Вы не можете вызывать ReadToEnd в обоих потоках, поскольку он будет блокировать одно или другое из результатов. Если вы хотите захватить stdout как stderr, вам нужно подписаться на события DataReceived и сохранить данные из аргументов события.

Следующий код в ваших окнах формирует приложение должно выглядеть следующим образом:

Process proc = new Process(); 
proc.StartInfo.FileName = @"console.exe"; 
proc.StartInfo.Arguments = "My args"; 
proc.StartInfo.CreateNoWindow = false; 
proc.StartInfo.RedirectStandardError = true; 
proc.StartInfo.RedirectStandardOutput = true; 
proc.StartInfo.UseShellExecute = false; 
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 

//store outcome of process 
var errors = new StringBuilder(); 
var output = new StringBuilder(); 
var hadErrors = false; 

// raise events 
proc.EnableRaisingEvents = true; 

// capture normal output 
proc.OutputDataReceived += (s, d) => { 
    output.Append(d.Data); 
}; 

// Capture error output 
proc.ErrorDataReceived += (s, d) => { 
    if (!hadErrors) 
    { 
     hadErrors = !String.IsNullOrEmpty(d.Data); 
    } 
    errors.Append(d.Data); 
}; 

proc.Start(); 
// start listening on the stream 
proc.BeginErrorReadLine(); 
proc.BeginOutputReadLine(); 

proc.WaitForExit(); 
string stdout = output.ToString(); 
string stderr = errors.ToString(); 

if (proc.ExitCode !=0 || hadErrors) 
{ 
    MessageBox.Show("error:" + stderr); 
} 

В консольном приложении теста теперь вы можете использовать потоки и установить ExitCode, если вам нравится:

try 
{ 
    Console.WriteLine("Ready ..."); 
    var cmd = Console.ReadLine(); 
    if (cmd == "e") 
    { 
     throw new Exception("boom"); 
    } else 
    { 
     Console.WriteLine("success!"); 
    } 
    Environment.ExitCode = 0; 
} 
catch(Exception e) 
{ 
    // write to stderr 
    Console.Error.WriteLine(e.Message); 
    // exit code to 1 
    Environment.ExitCode = 1; 
} 
Смежные вопросы