If I have set my program to be a Windows Application
, and used the AttachConsole(-1)
API, how do I get Console.WriteLine
to write to the console I launched the application from? It isn't working for me.
In case it is relevant, I'm using Windows 7 x64, and I have UAC enabled. Elevating doesn't seem to solve the problem though, nor does using start /wait
.
Update
Some additional background that might help:
I've just discovered that if I go to the command prompt and type cmd /c MyProgram.exe
, Then console output works. The same is true if I launch a command prompt, open a cmd.exe
sub-process, and run the program from that sub-shell.
I've also tried logging out and back in, running from a cmd.exe launched from the start menu (as opposed to right-click -> command prompt), and running from a console2 instance. None of those work.
Background
I've read on other sites and in several SO answers that I can call the win32 API AttachConsole
to bind my Windows Application to the console that ran my program, so I can have something that is "both a console application, and a Windows application".
For example, this question: Is it possible to log message to cmd.exe in C#/.Net?.
I've written a bunch of logic to make this work (using several other APIs), and I have gotten every other scenario to work (including redirection, which others have claimed won't work). The only scenario left is to get Console.WriteLine
to write to the console I launched my program with. From everything I've read this is supposed to work if I use AttachConsole
.
Repro
Here's a minimal sample - Note that the project is set to be a Windows Application
:
using System; using System.ComponentModel; using System.Runtime.InteropServices; using System.Windows.Forms; class Program { [STAThread] static void Main(string[] args) { if (!AttachConsole(-1)) { MessageBox.Show( new Win32Exception(Marshal.GetLastWin32Error()) .ToString() ); } Console.WriteLine("Test"); } [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] private static extern bool AttachConsole(int processId); }
AllocConsole
in my real app).If I call Marshal.GetLastWin32Error
after the call to Console.WriteLine
, I get the error "System.ComponentModel.Win32Exception (0x80004005): The handle is invalid". I suspect that attaching to the console is causing Console.Out
to get messed up, but I'm not sure how to fix it.
This is how I do it in Winforms. Using WPF would be similar.
static class SybilProgram { [STAThread] static void Main(string[] args) { if (args.Length > 0) { // Command line given, display console if ( !AttachConsole(ATTACH_PARENT_PROCESS) ) // Attach to a parent process console (-1) AllocConsole(); // Alloc a new console if none available ConsoleMain(args); } else { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); // instantiate the Form } } private static void ConsoleMain(string[] args) { Console.WriteLine("Command line = {0}", Environment.CommandLine); for (int ix = 0; ix < args.Length; ++ix) Console.WriteLine("Argument{0} = {1}", ix + 1, args[ix]); Console.ReadLine(); } [System.Runtime.InteropServices.DllImport("kernel32.dll")] private static extern bool AllocConsole(); [System.Runtime.InteropServices.DllImport("kernel32.dll")] private static extern bool AttachConsole(int pid); }
I cannot see any significant difference between our implementations. For what it is worth, below is what I have in my application and it works fine. I also create a sample WPF application and it also worked fine.
I suspect that your issue is elsewhere. Sorry I couldn't be more help.
[STAThread] public static void Main() { AttachProcessToConsole(); } private static void AttachProcessToConsole() { AttachConsole(-1); } // Attaches the calling process to the console of the specified process. // http://msdn.microsoft.com/en-us/library/ms681952%28v=vs.85%29.aspx [DllImport("Kernel32.dll")] private static extern bool AttachConsole(int processId);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With