2009-09-11 97 views
12

我需要調用一個第三方庫,它將一堆東西發送到控制檯。代碼只是這樣...抑制第三方庫控制檯輸出?

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

是否有一種簡單的方法來抑制來自ThirdPartyLibrary的不需要的控制檯輸出?出於性能原因,解決方案中不能使用新的進程或線程。

回答

12

那麼你可以使用Console.SetOutTextWriter實現不隨地寫:

Console.SetOut(TextWriter.Null); 

這將抑制所有控制檯輸出雖然。您始終可以保留對原始 Console.Out書寫器的引用,並將其用於您自己的輸出。

+0

這在大多數情況下工作。但是,在我的情況下,它不。外部庫創建一個COM對象和至少一個其他線程 - 可能甚至是另一個進程,這使我的問題變得複雜。 – noctonura 2009-09-11 18:16:04

+1

啊。如果最初知道它......如果它正在創建其他進程或以不同於使用「Console.WriteLine」等的方式編寫控制檯,那確實會使事情變得更加困難...... – 2009-09-11 18:22:46

+0

是的 - 對不起,在嘗試你的建議之前,我沒有意識到這很重要。 – noctonura 2009-09-11 18:31:02

0

這裏有一個辦法做到這一點(這也通常包括託管C++應用程序,您的P/Invoke從C#或其他方式):

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); 
    } 
} 

這個類可以如下叫:

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

這會產生影響。任何在OutputSink期間嘗試從另一個線程使用控制檯的應用程序邏輯將無法正確寫入標準輸出,標準錯誤,控制檯輸出或控制檯錯誤。