19

I've written a Windows service in C# using the ServiceBase helper. During its execution, some procedures in an external native DLL are called. Annoyingly, those procedures write to stdout and/or stderr in an uncontrolled manner as no sources are given for this DLL.

Is it possible to redirect those outputs from the C# service to a log file?

Pang
  • 9,073
  • 146
  • 84
  • 117
Herchu
  • 315
  • 1
  • 4
  • 8

2 Answers2

29

You can do this via PInvoke to SetStdHandle:

[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
}
Pang
  • 9,073
  • 146
  • 84
  • 117
Reed Copsey
  • 539,124
  • 75
  • 1,126
  • 1,354
  • 3
    I've changed the line handle = filestream.Handler; by handle = filestream.SafeFileHandle.DangerousGetHandle(); because filestream.Handler is deprecated. – Herchu Oct 19 '09 at 15:36
  • 1
    Any way to use this without a FileStream? (i.e. MemoryStream or similar)? – Steve Dec 18 '11 at 21:27
  • @ReedCopsey - Please see my reply to a similar comment on my new question: http://stackoverflow.com/questions/8555002/redirecting-native-dlls-stdout-to-memory-stream – Steve Dec 18 '11 at 22:18
  • @Herchu you did realise the "Dangerous" in DangerousGetHandle? It is there for a reason: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.safehandle.dangerousgethandle%28v=vs.100%29.aspx – Rui Marques Sep 01 '14 at 11:42
  • @RuiMarques Yeah, they call me Danger for a reason! :) Seriously now; that was 2009. If I happen to need it again I'll write it following Steve's solution. – Herchu Sep 03 '14 at 08:37
0

Check out the Console.SetOut method.

It will allow you to redirect console output to a TextWriter.

Pang
  • 9,073
  • 146
  • 84
  • 117
Jay Riggs
  • 52,110
  • 9
  • 138
  • 148