Detect whether I am being run from a Console application ?

  • Thread starter Thread starter Barry Mossman
  • Start date Start date
B

Barry Mossman

Hi,

can I detect whether my class is running within the context of a Console
application, vs say a WinForm's application ?

also does anyone know whether the compiler or runtime is smart enough to
avoid the overhead of writing to the console if it is not visible, eg I
am running inside a WinForm application.

thanks

Barry Mossman
 
You shouldn't write to the console directly from a library, instead, raise an
event and have the .exe that called it either write to the console, or
display a message, depending on whether it is a console or windows app.
 
Not sure if I remember this right. Don't all windows apps start with a
hidden console?
Detaching the apps default console, and attaching to "thee" Console that
started the WinForm app is a major pain that has some other issues IIRC.
Most folks solve this by distributing two loader apps. MyApp.exe and
MyApp.com in the same directory. If your at the console, myapp.com is found
first unless you explicitly type *.exe. You could also include a "-win"
switch in the console app to start the myapp.exe win app in the same
directory. Some of the MS apps are like this. Naturally people can just
create an icon pathed to myapp.exe to start the win app directly as normal.
 
William Stacey said:
Not sure if I remember this right. Don't all windows apps start with a
hidden console?
Detaching the apps default console, and attaching to "thee" Console that
started the WinForm app is a major pain that has some other issues IIRC.

Are you sure you're not thinking of Unix there? What you've described is
pretty much how it works for Unix applications that want to run without a
console, but it's definitely not how Windows works.

In Windows, you always have a standard output stream, but whether it's
attached to a console or not is usually determined by some flags in your
executable's header. (I say 'usually' because it is possible to write a
program that launches a process, hooking up whatever it likes as standard
input and output streams, but I assume we're talking about when programs are
launched in the usual way.)

The way it works is that if you are a console application you'll have a
console, if you're not, you won't. You can find out whether a given EXE is
a console app with the 'dumpbin' utility. (It's part of the Win32 SDK.)
Look at the 'subsystem' header value.

If the 'subsystem' is 3 ("Windows CUI") you're a console application. If
it's 2 ("Windows GUI") you're not.

You can't actually detach from the console once you've got it in Windows.
This is the whole reason people end up having to write two executables - a
..COM and a .EXE when they want to support both console and no-console
operation, as you describe here:
Most folks solve this by distributing two loader apps. MyApp.exe and
MyApp.com in the same directory.

If you initially had a console which you later detached from you wouldn't
need two executables. The reason for having two is so you can have one that
gets a console, and one that doesn't.

(Note that while you can create a console and attach your app to it after
launching, it'll be a whole new console window. The only way to attach to
the console of the command prompt from which you were launched is if you are
compiled as a console application.)


To answer one of Barry's original questions:

Well if you do a Console.WriteLine and there's no console, it will still
write the text to the standard output stream, whatever that is connected to.
This is because it might still be directed somewhere useful. For example,
WinDBG actually captures stdout and prints it to the debug output window for
applications it debugs. So you wouldn't necessarily want the runtime to
avoid writing console output to the standard output stream - just because
there's no console doesn't mean that output isn't being used by something.



As for the original question:

I don't think you can do this without interop. I've just looked at how
VS.NET 2005 (which has explicit support for interacting with the console
window) works it out, and it just uses the various console APIs. So you
could call the GetConsoleScreenBufferInfo API, for example, although you'd
need to get the raw console handle...

There isn't a managed API to do this.

[/QUOTE]
 
Are you sure you're not thinking of Unix there? What you've described is
pretty much how it works for Unix applications that want to run without a

Probably was. I just checked AllocConsole and it states GUI apps are
created without a console as you said. Each process can have one console
only. Many processes can attach to same console. So console.out on GUIss
must point to a null stream (bit bucket) by default and VS probably attaches
a stream to console.out to get the output window?

You can create a new console and attach it to GUI, but that is not want most
folks want. Normally they want to attach to the console that started the
exe. I think I have seen that done in a hackish way, but think it had some
issues after closing console and/or gui or some other strange issues so not
sure there is fool proof way to do it currently. If there was, that sure
would be a nice feature to change in windows. No expert here, but I think
the loader could just place a handle to the current console somewhere so the
windows app could find it *directly if needed and attach to it. I think
this could eliminate the need to create two apps. Please advise if I am
in left field here. tia.
 
Well if you do a Console.WriteLine and there's no console, it will
still write the text to the standard output stream, whatever that is
connected to. This is because it might still be directed somewhere
useful. For example, WinDBG actually captures stdout and prints it to
the debug output window for applications it debugs. So you wouldn't
necessarily want the runtime to avoid writing console output to the
standard output stream - just because there's no console doesn't mean
that output isn't being used by something.

Thanks for the response. I was writing something to produce trace output
of exceptions. I have attached a Listener to output to a file. If the
application that was using me was going to have a visible console I was
going add a Listener for the console screen.
I don't think you can do this without interop. I've just looked at how
VS.NET 2005 (which has explicit support for interacting with the
console window) works it out, and it just uses the various console
APIs. So you could call the GetConsoleScreenBufferInfo API, for
example, although you'd need to get the raw console handle...

There isn't a managed API to do this.

Thanks. I may look into this just an interesting exercise.

Barry Mossman
 
Back
Top