AttachConsole () shows the channel data, but the operator> does not redirect the file to file

I made a WinForm application running on .Net Framework 4.0. It writes to the parent console using the Console.WriteLine () method after calling -once at startup - win32 api AttachConsole (-1).

It works flawlessly, while I just need to show the output on the screen. Unfortunately, when I use the package with the pipe redirection operator as follows:

application.exe> ​​output.txt

it just creates an empty file. Maybe there is some kind of problem with the actual processing of the pipe when I use AttachConsole? Why can't the dos prompt catch data and put it in a file? Does anyone know of any issues with this scenario?

+4
source share
1 answer

Console.Out initialized lazily. The first time it is accessed, the run time calls GetStdHandle(STD_OUTPUT_HANDLE) to get the standard output descriptor. If this call occurs before the AttachConsole called, you get a file descriptor for redirection. If this call comes up after that, you get a console output descriptor.

The following class corrects standard output and error descriptors. If you run the application from the console, you will notice that after the next request any output will appear. You can avoid this with start /wait .

 using System; using System.Runtime.InteropServices; namespace SomeProject { class GuiRedirect { [DllImport("kernel32.dll", SetLastError = true)] private static extern bool AttachConsole(int dwProcessId); [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr GetStdHandle(StandardHandle nStdHandle); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool SetStdHandle(StandardHandle nStdHandle, IntPtr handle); [DllImport("kernel32.dll", SetLastError = true)] private static extern FileType GetFileType(IntPtr handle); private enum StandardHandle : uint { Input = unchecked((uint)-10), Output = unchecked((uint)-11), Error = unchecked((uint)-12) } private enum FileType : uint { Unknown = 0x0000, Disk = 0x0001, Char = 0x0002, Pipe = 0x0003 } private static bool IsRedirected(IntPtr handle) { FileType fileType = GetFileType(handle); return (fileType == FileType.Disk) || (fileType == FileType.Pipe); } public static void Redirect() { if (IsRedirected(GetStdHandle(StandardHandle.Output))) { var initialiseOut = Console.Out; } bool errorRedirected = IsRedirected(GetStdHandle(StandardHandle.Error)); if (errorRedirected) { var initialiseError = Console.Error; } AttachConsole(-1); if (!errorRedirected) SetStdHandle(StandardHandle.Error, GetStdHandle(StandardHandle.Output)); } } } 
+11
source

All Articles