Windows application that optionally remains attached to console - windows

I've got a Windows application (written in C, compiled with MSVC Express edition, 32-bit mode), which has two main modes of operation:
Windowed mode -- create a window, and draw stuff in it (namely, a fractal).
Benchmark mode -- when run with --benchmark as an argument, don't make a window but just print some benchmark statistics to stdout.
During development I've compiled as a Console app, and used SDL to create the window and perform other GUI functions. So benchmark mode runs fine (no window is created), and graphical mode just has a lingering console window.
However for my release compilation I've enabled the Windows subsystem instead of Console. (As explained in this question). This works great except I've suddenly discovered I can't run benchmarks any more. :o
I'm just wondering, is there a way for an application to choose at run time (e.g. based on the command line it's given) which kind of subsystem behaviour to use?
I've done some experimentation with EXE files in Windows (explorer, notepad, winword) and none of them seem to print anything to the console when run with an argument like "/?" (which most Windows console apps support). So it doesn't look like it, but I thought it's worth asking here in case there's a special trick.
Update. It looks like, no, you can't. Thanks for the answers guys.
Additional academic question. Does this mean that the subsystem choice is marked in the EXE header, and it's the operating system that examines this and sets up the Window or connects it to the console it's run from? I don't know much about EXE loading, but I would be curious to learn a few details here.
Conclusion. I think there are four good solutions (plus two semi-solutions, making five total :p) to choose from:
Use the console subsystem, but use FreeConsole when running in GUI mode.
Use the windows system, and use AllocConsole when running in benchmark mode. Not perfect if fractal.exe is run from an existing console, so I'll count this as half a solution ;-).
Just have one executable for each subsystem, fractal.exe and fractalgui.exe.
Have two (or more) executables, one of which does the work and passes it to the other to be displayed on the console or in a Window as appropriate. Needs some thought on how to divide the programs and how to communicate between them.
Another half-solution: have fractalgui.exe print the benchmark to standard out, and pipe that to a utility that will simply print it.
I haven't yet chosen, but I'm leaning towards #3.
Thanks to Matteo and smerlin for the ideas!

There is no way a application can choose her subsystem at runtime (well there are some really ugly workarounds, but those are full of quirks).
Then general solution for this problem is to have a console application, which starts your gui application if necessary
For your benchmark case, it would just print your benchmark statistics.
example setup:
- fractalgui.exe (subsystem: windows)
- fractal.exe (subsystem: console)
* the shortcut on the user desktop links to your fractalgui.exe
* if the user starts fractal.exe from the console, fractal exe starts fractalgui.exe
* if the user starts fractal.exe --benchmark, it either does the benchmark itself (if its possible to add this benchmark logic to another executable) and prints the information directly to console, or - if thats not possible - it will need to start fractalgui.exe --nogui --benchmark. The tricky case here is to get your output from fractalgui.exe to fractal.exe, so you can print it on the appropriate console. There are several ways to do this, e.g. named pipes (there are ways to start fractalgui.exe in a way, that you can just use stdout / cout there, and the data will be piped to the stdout of fractal.exe, but i dont recall how excactly this works anymore (edit: maybe this works)). The easiest way would be to start fractalgui.exe --nogui --benchmark > mylogfile and then print mylogfile after fractalgui.exe finished (since stdout/cout of fractalgui.exe will work if the output is redirected to a file), however you wont get "live" output, since all the output will be printed on the console when fractalgui.exe is already finished.

To add to #smerlin's answer, the other oft-seen method (cited into the articles I linked inside the comment) is to mark your application as a console application, but free the console (using FreeConsole) when you determine that you don't need it.
This is how ildasm does it, but it has the disadvantage of flashing the console for a brief moment between the start of the application and the call to FreeConsole.
Additional academic question. Does this mean that the subsystem choice is marked in the EXE header, and it's the operating system that examines this and sets up the Window or connects it to the console it's run from? I don't know much about EXE loading, but I would be curious to learn a few details here.
Yes, the loader checks the PE header and sets up everything according to the subsystem specified here.
Contrast with the *NIX approach: no executable is "special", and everyone has a working stdin/stdout/stderr; applications that want to display something will call the appropriate functions of Xlib. The drawback is that GUI applications have no clue if the application you are starting normally uses the console, so the system has to ask if you want to spawn also a terminal emulator or to discard the standard streams and just wait for it to spawn a window (obviously shortcuts store this information).

I described a technique for achieving this in my question here.
Matteo already mentioned the .com trick, but that's only part of a viable solution.

Related

How do I open a program in a Win32 Console without cmd.exe?

I have little previous experience with Windows (for programming, anyway), but recognizing that Windows has an enormous market share, I am trying to support it in my programs (even though they are just for fun, I like to pretend they're big projects). I have written a tiny shell with minimal (and when I say minimal, I mean minimal) features.
I am trying to port it to Windows and would like to use it independently from cmd.exe in a Win32 Console window (meaning the shell part of cmd.exe isn't running at all, but the window used for it shows). I have already done most of the other porting stuff such as build system (CMake) and changing appropriate Unix syscalls to Windows ones in a #define. I have done a little research and found little on this topic, however. I know it is possible because I've seen it done with Bash. Visual Studio also used to do it when I ran a program in its GUI.
Reference article I got some of this info from: https://en.wikipedia.org/wiki/Win32_console
Note: What I mean is when you click on it and it opens it without running cmd in its own little console window. Or when you type it into cmd it opens in a separate window that isn't running cmd. I am assuming cmd.exe and the console window it runs in are two separate things, but if I am wrong, please let me know. :)
This question is inspired by https://askubuntu.com/questions/111144/are-terminal-and-shell-the-same and a similar question where I got that Wikipedia link. Someone said that the console window and the shell were separate. I was writing my own shell so I started to wonder how to make mine independent of the default one.
The Win32 Console and cmd.exe are two different things. Windows automatically opens a console window when a program that needs one is started. It decides whether do to so by switches hard-wired into the executable. This window will be running said program. If the program that started the process is running in a console window, the two programs will share that console window.
As Noodles said, it really is that simple. You just start it. Double-clicking on it will do it. The CreateProcess() function with CREATE_NEW_CONSOLE passed to it will do it. Running the program from cmd.exe with
start <command>
will do it.
There is also a family of functions in the Windows API, called FreeConsole() and AllocConsole() that will free a program from its current console and create a new console for it, respectively.
Reference link (given by Noodles): https://msdn.microsoft.com/en-us/library/windows/desktop/ms682010(v=vs.85).aspx

How to detect from console or GUI app was run?

Is it's possible to detect inside app from where it was run? From cmd/bash or from GUI? Assume that we are working in graphical mode, not in pure console.
Not really, but sort of. Short answer: better not to try, get the user to tell you via an argument, which you can pre-fill in a shortcut.
Long answer:
In both cases, the program is launched in a similar way: the shell application (whether cmd/bash or Windows explorer/whatever gui launcher linux has) call CreateProcess or ShellExecute on Windows or fork+exec on Linux and the way the user executed it gets lost.
However, the process does have a parent ID which might be useful.... but it isn't reliable either for a few reasons: telling if it is a gui or command line shell isn't easy (best you can do is look at the image name) and the parent might terminate as soon as you launch, so there'd be no parent! (Linux gui apps often fork themselves to detach from the terminal. Of course, if you do this you'd probably know, but if you use a library it might happen without you realizing it.)
Well, the fact that I'm going off on parenthetical asides after every sentence shows how unreliable and complicate that is. If you want to try though, looking at your parent process ID before doing any fork/detaching might be helpful.
BTW looking for a parent console isn't very helpful: a Windows GUI subsystem program won't attach to the parent console even if one exists and a Linux GUI program may attach to the controlling tty of the X window manager.
What I'd actually recommend though is passing an argument to your function to tell it how it got started. When you create the GUI shortcut, make it automatically pass the "started by gui" argument to you. Then you can check args for it and react accordingly.
It still isn't perfect, but it is fairly easy to implement and probably good enough - gui launchers would probably use a shortcut anyway and you can pass arguments through them, so the user doesn't need to know about how it is implemented.
Or you could install two programs, one which is convenient from the command line and one which is optimized for the gui environment.
But I think that's the best you can do.

Is it's possible make GUI and console app in one exe?

I want to develop App with GUI, that can be run without showing GUI. How I can do it?
If it's possible would this App work on servers that do not have nothing related with GUI (ex: can I work with such App with ssh or so).
Any example please if it's possible.
Yes, it isn't always easy though and might not be worth it. The general idea is to write a console program that attempts to dynamically load the gui libraries and create a window. If that succeeds, it detaches from the console/controlling terminal and becomes a gui program. On Windows, this may pop up a console window briefly when the user double clicks the exe as it would be created first, then quickly destroyed.
You would want to dynamically load the gui with dlopen/LoadLibrary because the libs might not even be present on the computer you're running on, and if you rely on the system to load them at startup, your program won't run at all when they are missing. This is the most painful part - checking the return value of XOpenDisplay or CreateWindow or whatever is easy, and detaching from a console is easy (FreeConsole or fork). But first you need to get your program to actually start in the worst case scenario of no client side gui libraries at all.
If you're ok with ignoring that case - if the libs are present but the display isn't, you just handle it as a regular runtime error - then it isn't too hard at all.

Win GUI App started from Console => print to console impossible?

this is not yet another "I need a console in my GUI app" that has been discussed quite frequently. My situation differs from that.
I have a Windows GUI application, that is run from a command line. Now if you pass wrong parameters to this application, I do not want a popup to appear stating the possible switches, but I want that printed into the console that spawned my process.
I got that far that I can print into the console (call to AttachConsole(...) for parent process) but the problem is my application is not "blocking". As soon as I start it, the command prompt returns, and all output is written into this window (see attached image for illustration).
I played around a bit, created a console app, ran it, and see there, it "blocks", the prompt only re-appears after the app has terminated. Switching my GUI app to /SUBSYSTEM:Console causes strange errors (MSVCRTD.lib(crtexe.obj) : error LNK2019: nonresolved external Symbol "_main" in function "___tmainCRTStartup".)
I have seen the pipe approach with an ".exe" and a ".com" file approach from MSDEV but I find it horrible. Is there a way to solve this prettier?
This is not behaviour that you can change by modifying your application (aside from re-labelling it as already discussed). The command interpreter looks at the subsystem that an executable is labelled with, and decides whether to wait for the application to terminate accordingly. If the executable is labelled as having a GUI, then the command interpreter doesn't wait for it to terminate.
In some command interpreters this is configurable. In JP Software's TCC/LE, for example, one can configure the command interpreter to always wait for applications to terminate, even GUI ones. In Microsoft's CMD, this is not configurable behaviour, however. The Microsoft answer is to use the START command with the /WAIT option.
Once again: This is not the behaviour of your application. There is, apart from relabelling as a TUI program, no programmatic way involving your code to change this.
Maybe write a console-based wrapper app that checks the parameters, prints the error message on bad parameters, and calls/starts up the actual program when the parameters are correct?

How to prevent error pop-up message box for failed program (.exe) when running batch file

I'm running a test script from batch file.
Because it is test, the programs are expected to fail once in a while. It is file as long as error code is returned so I can continue and mark specific test as failed.
However there is very annoying behavior of executable files under Microsoft Windows - if something fails it pop-ups window like:
This application has failed to start because foo.dll was not found, Re-installing the application may fix the problem
<OK>
Or even better:
The instruction at "..." referenced to memory at "..." ..
Click on OK to terminate the program
Click on CANCEL to debug the program
The result is known - the script execution blocks till somebody presses "Ok" button. And when we talk about automatic scripts that may run automatically at night in some headless virtual machine, it may be very problematic.
Is there a simple way to prevent such behavior and just make an application to exit with failure code - without changing the code of the program itself?
Is this possible at all?
The answer is following: You need to disable WER.
Simplest description for this I found at http://www.noktec.be/archives/259
Simply (ON XP): Right Click on My Computer > Advanced > Error Reporting > Disable
Voila - programs crash silently!
This does not solves problem when DLL is missing, but this is much rare case and this is good enough for me.
You can suppress AV's and such from showing a dialog box by running your application, or the script (the script engine, like cscript.exe), under a debugger.
Use Gflags.exe, or modify the registry directly, and set Image File Execution Options for the image in question. See this article for details on how to use the appropriate registry keys. You can set it up using a debugger commandline like "C:\Debuggers\ntsd.exe -g -G -c'command'", where you can pass commands to ignore certain types of exceptions in the -c"commmand" argument. This will effectively give you a tool to suppress interactive dialogs as a result of exceptions like AV, and will let the process continue (presumably to immediate end after the exception has occured).
This article explains the commands you can use to control exceptions and events from withing the debugger.
The -g and -G flags make sure that the process won't break into the debugger automatically during process start and end respectively. You'll have to play with the various exception suppression options to make sure that you 'eat' all possible first and second chance exceptiosn that might cause the process to break into the debugger.
Also, if you can tolerate a process being broken into the debugger (as against being stuck showing a dialog box), perhaps that would be a better option overall. You can evaluate each debug break in batch mode at a later time and decide which bugs you care to fix.
It is possible. We used to use IBM's Rational Robot product which could monitor the screen for specific items and, if found, send keystrokes to windows and other sorts of things.
We actually used it for fully automated unit and system testing, much like you're trying to do.
Now I thought that Robot has been through quite a few name changes so it may be hard to find but there it is, right on IBM's web page and with a free downloadable trial for you. It's not cheap, clocking in at a smidgeon under USD5,000 but it was worth it for us.
There's also TestComplete where you could get a licence for just unedr USD1,000 - it touts "Black-box testing - Functional testing of any Windows application" as one of its features and also has a downloadable demo to see if it's suitable before purchase.
However, you may be able to find another product to do the same sort of thing.
I initially thought of Expect but the ActiveState one seems to concentrate on console applications which leads me to believe it may not do graphics well.
The only other option I can suggest is to write your own program in VBScript. I've done this before to automate the starting of many processes (log on to work VPN, start mail, log in and so on) so I could be fully set up with one mouseclick instead of having to start everything manually.
You can use AppActivate to bring a window to the foreground and SendKeys to send arbitrary keypresses to it after that. It's possible you may be able to cobble together something from that if you want a cheaper solution.

Resources