Redirecting stderr/stdout

Z

zaperaj

I have a C# application in which I'm trying to redirect some text written on to stderror. The text which is written to stderror is actually written bycalling a function that is present in some other dll. I have used CreatePipe, SetStdHandle and ReadFile (in that order) to achieve the mentioned functionality. While I am able to redirect any text that is written in the sameC# file using Console.SetError, the text that is written to stderr by the other dll still gets written on the native stderr and is not redirected.
Additionally, I'm not executing a new process and hence will not be able tochange its start info.
Is there any way to catch/redirect this text?
Also, I have read on the net some people mentioning about consoles being different for managed (in this case, my C# application) and unmanaged (in this case, where the dll might be using win32 functions to write to stderror) codes. If this is indeed the issue here, can it be overcome?
Thanks.
 
M

Marcel Müller

I have a C# application in which I'm trying to redirect some text written on to stderror. [...]
I have used CreatePipe, SetStdHandle and ReadFile (in that order) to achieve the mentioned functionality.
While I am able to redirect any text that is written in the same C# file using Console.SetError,
the text that is written to stderr by the other dll still gets written on the native stderr and is not redirected.
Additionally, I'm not executing a new process and hence will not be able to change its start info.

AFAIK SetStdHandle applies only to the .NET runtime. If the DLL uses
another runtime or is not even .NET is has no effect. At least not if it
is already running and has cached the I/O handles.
Is there any way to catch/redirect this text?

You need to do the redirection at Kernel level with the Win32 API.
Also, I have read on the net some people mentioning about consoles being different for managed (in this case, my C# application) and unmanaged (in this case, where the dll might be using win32 functions to write to stderror) codes.
Exactly.

If this is indeed the issue here, can it be overcome?

You need to replace the I/O handles of your own process. But be careful.
One process may hold more than one application apartment. Think of an
application pool. So you may not hit the nail on the head.

I would recommend to start the unmanaged code in a separate process and
pass redirected I/O handles before creation. The separate process could
still be a managed one using marshalling to the unmanaged DLL API. But
it is a separate process which has replaced I/O handles from the first
time. The concept is similar to plugin containers of modern browsers. Of
course, the drawback is that you have to pass all data through IPC and
maybe security issues. But yo have to concern with the latter anyway
with unmanaged DLLs.


Marcel
 
Z

zaperaj

I have a C# application in which I'm trying to redirect some text written on to stderror. [...]
I have used CreatePipe, SetStdHandle and ReadFile (in that order) to achieve the mentioned functionality.
While I am able to redirect any text that is written in the same C# file using Console.SetError,
the text that is written to stderr by the other dll still gets written on the native stderr and is not redirected.
Additionally, I'm not executing a new process and hence will not be able to change its start info.

AFAIK SetStdHandle applies only to the .NET runtime. If the DLL uses
another runtime or is not even .NET is has no effect. At least not if it
is already running and has cached the I/O handles.
Is there any way to catch/redirect this text?

You need to do the redirection at Kernel level with the Win32 API.
Also, I have read on the net some people mentioning about consoles being different for managed (in this case, my C# application) and unmanaged (inthis case, where the dll might be using win32 functions to write to stderror) codes.
Exactly.

If this is indeed the issue here, can it be overcome?

You need to replace the I/O handles of your own process. But be careful.
One process may hold more than one application apartment. Think of an
application pool. So you may not hit the nail on the head.

I would recommend to start the unmanaged code in a separate process and
pass redirected I/O handles before creation. The separate process could
still be a managed one using marshalling to the unmanaged DLL API. But
it is a separate process which has replaced I/O handles from the first
time. The concept is similar to plugin containers of modern browsers. Of
course, the drawback is that you have to pass all data through IPC and
maybe security issues. But yo have to concern with the latter anyway
with unmanaged DLLs.


Marcel


I have a C# application in which I'm trying to redirect some text written on to stderror. [...]
I have used CreatePipe, SetStdHandle and ReadFile (in that order) to achieve the mentioned functionality.
While I am able to redirect any text that is written in the same C# file using Console.SetError,
the text that is written to stderr by the other dll still gets written on the native stderr and is not redirected.
Additionally, I'm not executing a new process and hence will not be able to change its start info.

AFAIK SetStdHandle applies only to the .NET runtime. If the DLL uses
another runtime or is not even .NET is has no effect. At least not if it
is already running and has cached the I/O handles.
Is there any way to catch/redirect this text?

You need to do the redirection at Kernel level with the Win32 API.
Also, I have read on the net some people mentioning about consoles being different for managed (in this case, my C# application) and unmanaged (inthis case, where the dll might be using win32 functions to write to stderror) codes.
Exactly.

If this is indeed the issue here, can it be overcome?

You need to replace the I/O handles of your own process. But be careful.
One process may hold more than one application apartment. Think of an
application pool. So you may not hit the nail on the head.

I would recommend to start the unmanaged code in a separate process and
pass redirected I/O handles before creation. The separate process could
still be a managed one using marshalling to the unmanaged DLL API. But
it is a separate process which has replaced I/O handles from the first
time. The concept is similar to plugin containers of modern browsers. Of
course, the drawback is that you have to pass all data through IPC and
maybe security issues. But yo have to concern with the latter anyway
with unmanaged DLLs.


Marcel

Thanks Mr. Müller, very well explained.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top