2009-09-11 13 views
12

Devo chiamare una libreria di terze parti che capita di spargere un po 'di roba sulla console. Il codice semplicemente come questo ...Interrompe l'output della console della libreria di terze parti?

int MyMethod(int a) 
{ 
    int b = ThirdPartyLibrary.Transform(a); // spews unwanted console output 
    return b; 
} 

C'è un modo semplice per sopprimere l'output della console indesiderato da ThirdPartyLibrary? Per motivi di prestazioni, non è possibile utilizzare nuovi processi o thread nella soluzione.

risposta

12

Ebbene si può utilizzare Console.SetOut per un'implementazione di TextWriter, che non scrive da nessuna parte:

Console.SetOut(TextWriter.Null); 

che sopprimerà tutti output della console però. È sempre possibile mantenere un riferimento alloConsole.Out originale writer e utilizzarlo per il proprio output.

+0

Questo funziona nella maggior parte dei casi. Tuttavia, nel mio caso non è così. La libreria esterna crea un oggetto COM e almeno un altro thread, forse anche un altro processo, in modo da complicare il mio problema. – noctonura

+1

Ah. Sarebbe stato bello sapere che in origine ... se sta creando altri processi o scrivendo la console in modi diversi dall'uso di 'Console.WriteLine' ecc, ciò rende le cose molto più difficili ... –

+0

Sì - mi dispiace, Non avevo capito che era importante fino a quando non hai provato il tuo suggerimento. – noctonura

0

Ecco un modo per farlo (che pure di solito copre Managed C++ applicazioni che si P/Invoke da C# o altro):

internal class OutputSink : IDisposable 
{ 
    [DllImport("kernel32.dll")] 
    public static extern IntPtr GetStdHandle(int nStdHandle); 

    [DllImport("kernel32.dll")] 
    public static extern int SetStdHandle(int nStdHandle, IntPtr hHandle); 

    private readonly TextWriter _oldOut; 
    private readonly TextWriter _oldError; 
    private readonly IntPtr _oldOutHandle; 
    private readonly IntPtr _oldErrorHandle; 

    public OutputSink() 
    { 
     _oldOutHandle = GetStdHandle(-11); 
     _oldErrorHandle = GetStdHandle(-12); 
     _oldOut = Console.Out; 
     _oldError = Console.Error; 
     Console.SetOut(TextWriter.Null); 
     Console.SetError(TextWriter.Null); 
     SetStdHandle(-11, IntPtr.Zero); 
     SetStdHandle(-12, IntPtr.Zero); 
    } 

    public void Dispose() 
    { 
     SetStdHandle(-11, _oldOutHandle); 
     SetStdHandle(-12, _oldErrorHandle); 
     Console.SetOut(_oldOut); 
     Console.SetError(_oldError); 
    } 
} 

Questa classe può essere chiamato come segue:

using (new OutputSink()) 
{ 
    /* Call 3rd party library here... */ 
} 

Ciò avrà un impatto. Qualsiasi logica dell'applicazione che tenta di utilizzare la console da un altro thread durante il periodo di usingOutputSink non funzionerà correttamente per scrivere sullo standard output, errore standard, output della console o errore della console.

Problemi correlati