Wie zeichne ich Konsolenausgaben von einem Service C # auf?

Wir haben einen C# -Dienst, der auf einem Remote-Kundensystem bereitgestellt wird. Die Anwendung schreibt eine wesentliche Menge von "Diagnose" -Informationen in die Konsole (d. H. Console.WriteLine ()). Der Service ist nicht "tun, was es sollte". Wie können wir die Konsolenausgabe vom Dienst in einer anderen Anwendung erfassen?

In einer WinForm-Version kann die Anwendung am Kundenstandort geladen werden. Es funktioniert leider richtig.

Aktualisieren:

Wir können die Änderung des Dienstes ändern, möchten jedoch zu diesem Zeitpunkt keine größeren Änderungen vornehmen.

Wir protokollieren auch MSMQ, aber nur für "wichtige" Ereignisse. Dieser Dienst interagiert für seinen normalen Betrieb mit MSMQ. Oder zumindest sollte es. Der Dienst scheint Elemente aus MSMQ nicht zu ziehen, wenn die WinForm-Version dies tut. Daher könnte das Schreiben der Nachrichten, die an die Konsole gesendet werden, problematisch sein.

18

7 Antworten

Können Sie den Service-Code überhaupt ändern ? Wenn dies der Fall ist, wäre die Verwendung von Console.SetOut zum Schreiben in eine Datei der offensichtlichste erste Anlaufhafen. Wechseln Sie dann zu einer geeigneten Protokollbibliothek für die nächste Version :)

31
hinzugefügt
Die Verwendung von Console.SetOut war minimal genug, um genügend Informationen zu erhalten, um das Problem mit dem Dienst zu ermitteln.
hinzugefügt der Autor Mike Chess, Quelle

Im Allgemeinen sollten Sie es vermeiden, Diagnoseinformationen direkt in die Konsole, das Ereignisprotokoll, MSMQ oder anderswo aus Ihrem Anwendungscode zu schreiben. Rufen Sie stattdessen eine Protokollierungs-API auf und verwenden Sie die Konfiguration, um die Ausgabe wo immer Sie möchten umzuleiten.

Beispielsweise könnten Sie die gesamte Console.WriteLine durch Trace.WriteLine (*) ersetzen. Anschließend können Sie die Ausgabe an die Konsole, eine Datei oder an eine andere Stelle umleiten, indem Sie die Anwendungskonfigurationsdatei ändern: Verwenden Sie beispielsweise zur Ausgabe an die Konsole einen ConsoleTraceListener, etwa:


  
    <trace autoflush="false" indentsize="4">
      
        
      
    
  
 

Während der Fehlersuche erhalten Sie Ihre Ausgabe auf der Konsole - auf der Kundenseite würden Sie sie so konfigurieren, dass sie die Ausgabe der Ablaufverfolgung in eine Datei, in das Ereignisprotokoll oder ähnliches umleitet.

Noch besser, verwenden Sie ein Logging-Framework von Drittanbietern (ich würde Log4Net empfehlen), das Ihnen mehr Möglichkeiten als System.Diagnostics.Trace bietet.

(*) Trace.Write/Trace.WriteLine sind die gleichen wie Debug.Write/Debug.WriteLine, außer dass letztere nur kompiliert werden, wenn das DEBUG-Symbol definiert ist. Ziehen Sie Trace to Debug vor, wenn die Ausgabe in Release-Builds verfügbar sein soll.

12
hinzugefügt

Du hast eine Menge Optionen; Weiterleiten der Konsolenausgabe in eine Datei und Verwenden einer geeigneten Protokollierungsbibliothek wie erwähnt, sind zwei gute. Hier ist eine mittlere Option: Schreiben Sie in das Ereignisprotokoll.

EventLog log;
string logsource = "MyService";

// execute once per invocation
if (!System.Diagnostics.EventLog.SourceExists(logsource))
{
    System.Diagnostics.EventLog.CreateEventSource(
        logsource, "Application");
}
log = new EventLog();
log.Source = logsource;
log.Log = "Application";

// replace console logging with this
log.WriteEntry(message, EventLogEntryType.Information);

Then look for entries in the Application event log (Administrative Tools -> Event Viewer) where Source = "MyService".

5
hinzugefügt

benutze debug.writeline und benutze sysinternals debugview?

3
hinzugefügt
oder log4net das nächste Mal und konfigurieren Sie das Ziel.
hinzugefügt der Autor kenny, Quelle

Ich würde Console.WriteLine überhaupt nicht von einem Fensterdienst verwenden. Sie sollten diese Fehler wahrscheinlich in einer Protokolldatei protokollieren.

Eine andere Möglichkeit, dies zu tun, so dass mehrere Anwendungen die Protokolle konsumieren können, besteht darin, die Protokollnachrichten in eine MSMQ-Warteschlange zu stellen.

3
hinzugefügt

Ich fand diesen Beitrag auf MSDN, die die Console-Ausgabe an eine Rich-Text-Box bindet, funktionierte für mich sehr schnell und einfach.

Es überschreibt WriteLine und kann erweitert werden, um andere Methoden zu überschreiben.

1
hinzugefügt

So habe ich die Konsolenausgabe eines unter Windows 7 ausgeführten Diensts angesehen. Dies kann hilfreich sein, wenn Sie den Quellcode des Dienstes absolut nicht ändern können, um ihn in einer Datei zu protokollieren.

  1. Führen Sie services.msc aus, und bearbeiten Sie die Eigenschaften des Service. Aktivieren Sie auf der Registerkarte "Anmelden" die Option "Interaktion mit dem Desktop zulassen"

  2. Verwenden Sie den Registrierungseditor, um den ImagePath Ihres Dienstes zu ändern: Wechseln Sie zu HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet001 \ services \ [Ihr Dienstname], und bearbeiten Sie ImagePath. Hängen Sie cmd.exe/c an den Anfang der ImagePath-Zeichenfolge an. Wenn Ihr ursprünglicher ImagePath also c: \ myService \ myservice.exe lautet, sollte Ihr neuer ImagePath cmd.exe /cc:\myService\myservice.exe sein.

  3. Starten Sie Ihren Service. Sie sollten ein Popup-Fenster mit dem Titel "Interactive Services Detection" erhalten. Wählen Sie "Nachricht anzeigen". Ihr Bildschirm sollte den Kontext wechseln und das Konsolenfenster anzeigen. Wenn Sie fertig sind, klicken Sie auf die Schaltfläche "Jetzt zurückgeben".

  4. Wenn Sie mit dem Debugging fertig sind, ändern Sie ImagePath auf seinen ursprünglichen Wert zurück. Deaktivieren Sie dann das Kontrollkästchen "Dienst mit Desktop interagieren" in den Diensteigenschaften und starten Sie Ihren Dienst neu.

Warnung: Ich habe das nur mit einem Service gemacht und es hat für mich funktioniert. Ich weiß nicht, ob es für irgendeinen Dienst funktioniert oder ob es zu unerwarteten Ergebnissen führen wird, daher empfehle ich Ihnen dringend, dies nur in einer nicht produktiven Umgebung zu tun.

1
hinzugefügt