Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirect stdout+stderr on a C# Windows service

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?

like image 522
Herchu Avatar asked Oct 16 '09 16:10

Herchu


People also ask

How do you redirect stderr to stdout?

Understanding the concept of redirections and file descriptors is very important when working on the command line. To redirect stderr and stdout , use the 2>&1 or &> constructs.

How do I redirect stderr and stdout to a file?

The I/O streams can be redirected by putting the n> operator in use, where n is the file descriptor number. For redirecting stdout, we use “1>” and for stderr, “2>” is added as an operator. We have created a file named “sample. txt” to store the redirected output in our current directory.

Can stderr be redirected?

The regular output is sent to Standard Out (STDOUT) and the error messages are sent to Standard Error (STDERR). When you redirect console output using the > symbol, you are only redirecting STDOUT. In order to redirect STDERR, you have to specify 2> for the redirection symbol.


1 Answers

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
}
like image 161
Reed Copsey Avatar answered Sep 22 '22 04:09

Reed Copsey