2009-10-16 4 views
12

Ich habe einen Windows-Dienst in C# mit dem ServiceBase Helfer geschrieben. Während seiner Ausführung werden einige Prozeduren auf einer externen nativen DLL aufgerufen. Ärgerlicherweise schreiben diese Prozeduren unkontrolliert nach stdout und/oder stderr, da für diese DLL keine Quellen angegeben sind.Redirect stdout + stderr auf einem C# Windows-Dienst

Ist es möglich, diese Ausgaben aus dem C# -Dienst in eine Protokolldatei umzuleiten?

+0

Starten Sie die DLL als Prozess? oder einfach auf die DLL verweisen? –

+0

Sie können eine DLL nicht als Prozess starten. Dies ist ein häufiges Problem. –

Antwort

22

Sie können dies auf SetStdHandle über PInvoke tun:

[DllImport("Kernel32.dll", SetLastError = true) ] 
public static extern int SetStdHandle(int device, IntPtr handle); 

// in your service, dispose on shutdown.. 
FileStream filestream; 
StreamWriter streamwriter; 

void Redirect() 
{ 
    int status; 
    IntPtr handle; 
    filestream = new FileStream("logfile.txt", FileMode.Create); 
    streamwriter = new StreamWriter(filestream); 
    streamwriter.AutoFlush = true; 
    Console.SetOut(streamwriter); 
    Console.SetError(streamwriter); 

    handle = filestream.Handle; 
    status = SetStdHandle(-11, handle); // set stdout 
    // Check status as needed 
    status = SetStdHandle(-12, handle); // set stderr 
    // Check status as needed 
} 
+0

Danke. Ich werde das tun. – Herchu

+1

Ich habe die Zeile geändert handle = filestream.Handler; von handle = filestream.SafeFileHandle.DangerousGetHandle(); , da filestream.Handler veraltet ist. – Herchu

+1

Eine Möglichkeit, dies ohne einen FileStream zu verwenden? (d. h. MemoryStream oder ähnliches)? – Steve

0

Schauen Sie sich die Console.SetOut Methode.

Damit können Sie die Konsolenausgabe an einen TextWriter umleiten.

+1

Abhängig davon, wie die DLL geschrieben wird, leitet das die DLLs-Ausgabe jedoch nicht zur Konsole um. Normalerweise funktioniert es, aber nicht immer. –

+1

Reed, was hängt davon ab? – Stiefel