Note that there are some explanatory texts on larger screens.

plurals
  1. POIs it possible to build a Console app that does not display a console Window when double-clicked?
    text
    copied!<blockquote> <p>Related:<br> <a href="https://stackoverflow.com/questions/1117275/should-i-include-a-command-line-mode-in-my-applications">Should I include a command line mode in my applications?</a><br> <a href="https://stackoverflow.com/questions/377911/how-to-grab-parent-process-standard-output">How to grab parent process standard output?</a><br> <a href="https://stackoverflow.com/questions/510805">Can a console application detect if it has been run from Explorer?</a></p> </blockquote> <p>I want to build a console app, that is normally run from the command line. </p> <p>But, when it is double clicked from within Explorer (as opposed to being run from a cmd.exe prompt) then I'd like the program to NOT display a console window. </p> <p>I want to avoid this: </p> <p><a href="http://i36.tinypic.com/1088p5s.jpg" rel="nofollow noreferrer">alt text http://i36.tinypic.com/1088p5s.jpg</a></p> <p>Is it possible? </p> <p><strong>EDIT</strong> I guess another way to ask it is, <em>is it possible for a program to know how it was invoked - whether by double-click or by command line</em> ? </p> <p>I'm working in .NET, on Windows. </p> <p><strong>EDIT 2:</strong> From <a href="http://blogs.msdn.com/oldnewthing/archive/2009/01/01/9259142.aspx" rel="nofollow noreferrer">this <em>Old New Thing</em> blog post</a> I learned some good stuff. Here's what I know now...</p> <p>In Windows, EXE files are marked as either GUI or non-GUI. With csc.exe, this is selected with <code>/target:winexe</code> or <code>/target:exe</code>. Before the first instruction in the process executes, the Windows kernel sets up the execution environment. At that moment, if the EXE is marked GUI, the kernel sets the stdin/stdout for the process to NULL, and if non-GUI (command-line) the kernel creates a console and sets the stdin/stdout for the process to that console. </p> <p>When launching the process, if there is no stdin/stdout (== <code>/target:winexe</code>), then the call immediately returns. So, launching a gui app from a cmd.exe, you will immediately get your cmd prompt back. If there is a stdin/stdout, and if run from cmd.exe, then the parent cmd.exe waits for process exit. </p> <p>The "immediate return" is important because if you code a GUI app to attach to its parent's console, you will be able to do console.writeline, etc. But the cmd.exe prompt is active. The user can type new commands, start a new process, and so on. In other words, from a winexe, simply attaching to the parent console with <code>AttachConsole(-1)</code> will not "turn it into" a console app. </p> <hr> <p>At this point I think the only way to allow an app to use the console if it is invoked from cmd.exe, and NOT use it if it is double-clicked, is to define the exe as a regular console exe (<code>/target:exe</code>), and <em>hide the window</em> on startup if appropriate. You still get a console window appearing briefly. </p> <p>I still haven't figured how to know whether it was launched from explorer or cmd.exe, but I'm getting closer.. </p> <hr> <p><strong>ANSWERS</strong></p> <p>It is not possible to build a console app that does not display a console window. </p> <p>It <em>is possible</em> to build a console app that hides its window very quickly, but not so quickly that it is as if the window never appears. </p> <p>Now, to determine whether a console app was launched from explorer, some have suggested to look at the console it is running in<br> (from <a href="https://stackoverflow.com/questions/1528152/is-it-possible-to-build-a-console-app-that-does-not-display-a-console-window-when/1528271#1528271">mgb's answer</a>, and <a href="http://support.microsoft.com/kb/99115" rel="nofollow noreferrer">KB article 99115</a>) :</p> <pre><code> int left = Console.CursorLeft; int top = Console.CursorTop; bool ProcessWasRunFromExplorer = (left==0 &amp;&amp; top==0); </code></pre> <p>This tells you if the process was launched in its own console, but not whether it was explorer. A double click in explorer would do this, but also a Start.Process() from within an app would do the same thing. </p> <p>If you want to treat those situations differently, use this to learn the name of the parent process:</p> <pre><code> System.Console.WriteLine("Process id: {0}", Process.GetCurrentProcess().Id); string name = Process.GetCurrentProcess().ProcessName ; System.Console.WriteLine("Process name: {0}", name); PerformanceCounter pc = new PerformanceCounter("Process", "Creating Process Id", name); Process p = Process.GetProcessById((int)pc.RawValue); System.Console.WriteLine("Parent Process id: {0}", p.Id); System.Console.WriteLine("Parent Process name: {0}", p.ProcessName); // p.ProcessName == "cmd" or "Explorer" etc </code></pre> <p>To hide the window quickly after the process is launched, use this: </p> <pre><code> private static readonly int SW_HIDE= 0; [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow); .... { IntPtr myHandle = Process.GetCurrentProcess().MainWindowHandle; ShowWindow(myHandle, SW_HIDE); } </code></pre> <p>If you produce a <code>winexe</code> (a WinForms app), and optionally attach to the parent console when appropriate with <code>AttachConsole(-1)</code>, you do not get the equivalent of a regular console app. For a winexe, the parent process (like cmd.exe) will return to the command prompt immediately after starting a GUI application. In other words, the command prompt is active and ready for input while the just-launched process may be emitting output. This is confusing and is probably useful only for debugging winforms apps. </p> <p>This worked for me. </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload