2017-10-17 129 views
0

我在寫一個Windows服務和一個系統托盤應用程序來控制它。在我的服務中,我有很多log4net日誌記錄語句。我想在可從systray應用程序打開的窗口中顯示這些消息,並開始嘗試使用log4net TraceAppender。我還爲我的系統托盤應用程序添加了一個自定義的TraceListener。不幸的是,我沒有看到任何消息進入系統托盤應用程序。我不得不承認,甚至有可能在另一個應用程序中收到這些消息。接收由另一個應用程序中的TraceAppender發送的log4net消息

在我的服務我添加以下行到我的log4net.xml:

<appender name="TraceAppender" type="log4net.Appender.TraceAppender"> 
    <immediateFlush value="true" /> 
    <layout type="log4net.Layout.PatternLayout"> 
    <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" /> 
    </layout> 
</appender> 

我也使用文件附加目的地,所以在根節我有這些行:

<root> 
    <level value="WARN" /> 
    <appender-ref ref="RollingFileAppender" /> 
    <appender-ref ref="TraceAppender" /> 
</root> 

請注意,消息到達日誌文件就好了。

在系統托盤的應用程序,添加以下類:

class TextBoxTraceListener : TraceListener 
{ 
    private static TextBox _target; 
    private StringSendDelegate _invokeWrite; 

    public TextBoxTraceListener() 
    { 
    } 

    public TextBoxTraceListener(TextBox target) 
    { 
     _target = target; 
     _invokeWrite = new StringSendDelegate(SendString); 
    } 

    public override void Write(string message) 
    { 
     if (_target != null) 
     { 
      _target.Invoke(_invokeWrite, new object[] { message }); 
     } 
    } 

    public override void WriteLine(string message) 
    { 
     if (_target != null) 
     { 
      _target.Invoke(_invokeWrite, new object[] 
      { message + Environment.NewLine }); 
     } 
    } 

    private delegate void StringSendDelegate(string message); 
    private void SendString(string message) 
    { 
     // No need to lock text box as this function will only 
     // ever be executed from the UI thread 
     _target.Text += message; 
    } 
} 

我添加的構造不帶參數的,因爲我得到了一個例外,沒有構造函數都會被找到。

我的對話框類(的WinForms)的代碼是這樣的:

public partial class LogWatcherForm : Form 
{ 
    TextBoxTraceListener _textBoxListener; 

    public LogWatcherForm() 
    { 
     InitializeComponent(); 
    } 

    private void LogWatcherForm_Load(object sender, EventArgs e) 
    { 
     _textBoxListener = new TextBoxTraceListener(logTextBox); 
     Trace.Listeners.Add((TraceListener)_textBoxListener); 
    } 
} 

最後,系統托盤應用程序的app.config中包含:

<system.diagnostics> 
    <trace autoflush="false" indentsize="4"> 
    <listeners> 
     <add name="myListener" type="Cordis.ServiceSysTray.TextBoxTraceListener,ServiceSysTray"/> 
     <remove name="Default" /> 
    </listeners> 
    </trace> 
</system.diagnostics> 

我希望有人能指出我在正確的方向得到這個工作。這可以使用TraceAppender工作嗎?

回答

0

你有兩個過程。使用log4net和TraceAppender在Windows服務中執行Trace.WriteLine。在第二個過程中,應用程序在系統托盤中運行,您正在通過自定義TraceListener進行偵聽。

Trace.WriteLine未廣播,因此所有進程都可以接收它。修復代碼的方法是在系統托盤應用程序中,添加一個FileSystemWatcher監視Windows服務進程生成的日誌文件。每次更新日誌文件時,將新值讀入系統托盤應用程序並顯示它們。當您打開日誌文件時,請確保您不要專門使用文件訪問。

相關問題