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);
}
- When I run this from a command prompt, I don't get an error, but I don't get any console output either. This is the problem
- If I add extra message boxes anywhere in the execution flow of the app, the message box gets displayed. I expect this, so all good here.
- When I run this from Visual Studio or by double clicking on it, a message box with an error is displayed. I expect this, so no worries here (will use
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.
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.
I was suffering from the same problem with my application's current version (targeting .NET 4.0) but am sure
AttachConsole(-1)
did work as expected in earlier versions (which targeted .NET 2.0).I found that I could get console output as soon as I removed my (custom) TraceListener from my application's .exe.config file, even though I don't know why yet.
Perhaps this is what's swallowing your console output as well...
Update
In fact I had a
Console.WriteLine()
in my custom trace listener's c'tor which was messing things up. After removing this line, console output afterAttachConsole(-1)
went back to normal.Had the same problem and it appears that when running
cmd.exe
in Administrator modeAttachConsole()
call succeeds butConsole.Write()
andConsole.WriteLine()
don't work. If you runcmd.exe
normally (non-admin) everything seems to work fine.This is how I do it in Winforms. Using WPF would be similar.
Same problem here. I was using
gflags.exe
, (part of Debugging Tools for Windows) to attach a commandline WPF application tovsjitdebugger.exe
(See this post). As long as my application was coupled with vsjitdebugger.exe, no output was written to the console.From the moment I detached my application, output to the console, from where I launched my application, was restored.
I had a similar situation: could not get a Windows Application to output anything in the programmatically attached console. Eventually, it turned out that I was using Console.WriteLine once before AttachConsole, and that was tampering with everything that followed after.