2012-08-11 17 views
9

Ho una dll esterna scritta in C# e ho studiato dalla documentazione degli assembly che scrive i suoi messaggi di debug sulla console utilizzando Console.WriteLine.Reindirizzare console.writeline dall'applicazione Windows a una stringa

questa DLL scrive in console durante la mia interazione con l'interfaccia utente dell'applicazione, quindi non faccio chiamate DLL direttamente, ma vorrei acquisire tutta l'uscita della console, quindi penso di aver intialize nel caricamento del modulo, quindi ottenere quel testo catturato più tardi.

Vorrei reindirizzare tutto l'output a una variabile stringa.

Ho provato Console.SetOut, ma il suo uso per reindirizzare su stringa non è facile.

+0

Quale codice hai usato quando si cerca di utilizzare il metodo 'SetOut'? –

risposta

18

quanto sembra che si vuole prendere l'uscita della console in tempo reale, ho capito che si potrebbe creare il proprio TextWriter implementazione che attiva un evento ogni volta che un Write o WriteLine accade sul Console.

Lo scrittore si presenta così:

public class ConsoleWriterEventArgs : EventArgs 
    { 
     public string Value { get; private set; } 
     public ConsoleWriterEventArgs(string value) 
     { 
      Value = value; 
     } 
    } 

    public class ConsoleWriter : TextWriter 
    { 
     public override Encoding Encoding { get { return Encoding.UTF8; } } 

     public override void Write(string value) 
     { 
      if (WriteEvent != null) WriteEvent(this, new ConsoleWriterEventArgs(value)); 
      base.Write(value); 
     } 

     public override void WriteLine(string value) 
     { 
      if (WriteLineEvent != null) WriteLineEvent(this, new ConsoleWriterEventArgs(value)); 
      base.WriteLine(value); 
     } 

     public event EventHandler<ConsoleWriterEventArgs> WriteEvent; 
     public event EventHandler<ConsoleWriterEventArgs> WriteLineEvent; 
    } 

Se si tratta di un'applicazione WinForm, è possibile impostare lo scrittore e consumare i suoi eventi nei Program.cs come questo:

/// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     using (var consoleWriter = new ConsoleWriter()) 
     { 
      consoleWriter.WriteEvent += consoleWriter_WriteEvent; 
      consoleWriter.WriteLineEvent += consoleWriter_WriteLineEvent; 

      Console.SetOut(consoleWriter); 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new Form1()); 
     } 
    } 

    static void consoleWriter_WriteLineEvent(object sender, Program.ConsoleWriterEventArgs e) 
    { 
     MessageBox.Show(e.Value, "WriteLine"); 
    } 

    static void consoleWriter_WriteEvent(object sender, Program.ConsoleWriterEventArgs e) 
    { 
     MessageBox.Show(e.Value, "Write"); 
    } 
+0

questa DLL scrive in console durante la mia interazione con l'interfaccia utente dell'applicazione, quindi non faccio chiamate DLL direttamente, ma vorrei catturare tutto l'output della console, quindi penso di aver intialize nel caricamento del modulo, quindi ottenere quel testo catturato dopo. – geogeek

+0

È un'app WinForms? Quando nel flusso del programma hai bisogno dell'output? –

+0

sì, è un'app winform C#, ho bisogno di acquisire l'output della console dopo un evento della GUI. – geogeek

17

equivale in sostanza a quanto segue:

var originalConsoleOut = Console.Out; // preserve the original stream 
using(var writer = new StringWriter()) 
{ 
    Console.SetOut(writer); 

    Console.WriteLine("some stuff"); // or make your DLL calls :) 

    writer.Flush(); // when you're done, make sure everything is written out 

    var myString = writer.GetStringBuilder().ToString(); 
} 

Console.SetOut(originalConsoleOut); // restore Console.Out 

Quindi nel tuo caso quando si imposta questa funzione prima di effettuare chiamate verso la DLL di terze parti.

+0

questa DLL scrive in console durante la mia interazione con l'interfaccia utente dell'applicazione, quindi non faccio chiamate DLL direttamente, ma vorrei catturare tutto l'output della console, quindi penso di aver intialize nel caricamento del modulo, quindi ottenere quel testo catturato dopo. – geogeek

1

oppure si può avvolgilo in un metodo di supporto che prende del codice come argomento eseguirlo e restituisce la stringa che è stata stampata. Si noti come gestiamo con garbo le eccezioni.

public string RunCodeReturnConsoleOut(Action code) 
{ 
    string result; 
    var originalConsoleOut = Console.Out; 
    try 
    { 
    using (var writer = new StringWriter()) 
    { 
     Console.SetOut(writer); 
     code(); 
     writer.Flush(); 
     result = writer.GetStringBuilder().ToString(); 
    } 
    return result; 
    } 
    finally 
    { 
    Console.SetOut(originalConsoleOut); 
    } 
} 
0

è anche possibile chiamare setout con Console.OpenStandardOutput, questo sarà ripristinare il flusso di uscita originale:

Console.SetOut(new StreamWriter(Console.OpenStandardOutput())); 
Problemi correlati