WriteLine not producing expected result [duplicate] - c#

I'm studying C# by following the guides in MSDN.
Now, I just tried the Example 1 (here is the link to MSDN), and I've encountered an issue: why is the console window closing immediately once displayed my output?
using System;
public class Hello1
{
public static int Main()
{
Console.WriteLine("Hello, World!");
return 0;
}
}

the issue here is that their Hello World Program is showing up then it would immediately close.
why is that?
Because it's finished. When console applications have completed executing and return from their main method, the associated console window automatically closes. This is expected behavior.
If you want to keep it open for debugging purposes, you'll need to instruct the computer to wait for a key press before ending the app and closing the window.
The Console.ReadLine method is one way of doing that. Adding this line to the end of your code (just before the return statement) will cause the application to wait for you to press a key before exiting.
Alternatively, you could start the application without the debugger attached by pressing Ctrl+F5 from within the Visual Studio environment, but this has the obvious disadvantage of preventing you from using the debugging features, which you probably want at your disposal when writing an application.
The best compromise is probably to call the Console.ReadLine method only when debugging the application by wrapping it in a preprocessor directive. Something like:
#if DEBUG
Console.WriteLine("Press enter to close...");
Console.ReadLine();
#endif
You might also want the window to stay open if an uncaught exception was thrown. To do that you can put the Console.ReadLine(); in a finally block:
#if DEBUG
try
{
//...
}
finally
{
Console.WriteLine("Press enter to close...");
Console.ReadLine();
}
#endif

Instead of using
Console.Readline()
Console.Read()
Console.ReadKey()
you can run your program using Ctrl+F5 (if you are in Visual Studio). Then Visual Studio will keep the console window open, until you press a key.
Note: You cannot debug your code in this approach.

I assume the reason you don't want it to close in Debug mode, is because you want to look at the values of variables etc. So it's probably best to just insert a break-point on the closing "}" of the main function.
If you don't need to debug, then Ctrl-F5 is the best option.

This behaves the same for CtrlF5 or F5.
Place immediately before end of Main method.
using System.Diagnostics;
private static void Main(string[] args) {
DoWork();
if (Debugger.IsAttached) {
Console.WriteLine("Press any key to continue . . .");
Console.ReadKey();
}
}

In Visual Studio 2019 for .NET Core projects the console doesn't close automatically by default. You can configure the behaviour through menu Tools → Options → Debugging → General → Automatically close the console when debugging stops. If you get your console window automatically closing, check if the mentioned setting is not set.
The same applies to the .NET Framework new style console projects:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>
</Project>
The old style .NET Framework project still unconditionally close the console at the end (as of Visual Studio 16.0.1).
Reference: .NET Core tooling update for Visual Studio 2019 Preview 2

If you want to keep your application opened, you have to do something in order to keep its process alive. The below example is the simplest one, to be put at the end of your program:
while (true) ;
However, it'll cause the CPU to overload, as it's therefore forced to iterate infinitely.
At this point, you can opt to use System.Windows.Forms.Application class (but it requires you to add System.Windows.Forms reference):
Application.Run();
This doesn't leak CPU and works successfully.
In order to avoid to add System.Windows.Forms reference, you can use a simple trick, the so-called spin waiting, importing System.Threading:
SpinWait.SpinUntil(() => false);
This also works perfectly, and it basically consists of a while loop with a negated condition that is returned by the above lambda method. Why isn't this overloading CPU? You can look at the source code here; anyway, it basically waits some CPU cycle before iterating over.
You can also create a message looper, which peeks the pending messages from the system and processes each of them before passing to the next iteration, as follows:
[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "PeekMessage")]
public static extern int PeekMessage(out NativeMessage lpMsg, IntPtr hWnd, int wMsgFilterMin, int wMsgFilterMax, int wRemoveMsg);
[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "GetMessage")]
public static extern int GetMessage(out NativeMessage lpMsg, IntPtr hWnd, int wMsgFilterMin, int wMsgFilterMax);
[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "TranslateMessage")]
public static extern int TranslateMessage(ref NativeMessage lpMsg);
[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "DispatchMessage")]
public static extern int DispatchMessage(ref NativeMessage lpMsg);
[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode]
public static bool ProcessMessageOnce()
{
NativeMessage message = new NativeMessage();
if (!IsMessagePending(out message))
return true;
if (GetMessage(out message, IntPtr.Zero, 0, 0) == -1)
return true;
Message frameworkMessage = new Message()
{
HWnd = message.handle,
LParam = message.lParam,
WParam = message.wParam,
Msg = (int)message.msg
};
if (Application.FilterMessage(ref frameworkMessage))
return true;
TranslateMessage(ref message);
DispatchMessage(ref message);
return false;
}
Then, you can loop safely by doing something like this:
while (true)
ProcessMessageOnce();

The program immediately closes because there's nothing stopping it from closing. Insert a breakpoint at return 0; or add Console.Read(); before return 0; to prevent the program from closing.

Alternatively, you can delay the closing using the following code:
System.Threading.Thread.Sleep(1000);
Note the Sleep is using milliseconds.

Another way is to use Debugger.Break() before returning from Main method

The code is finished, to continue you need to add this:
Console.ReadLine();
or
Console.Read();

Use Console.Read(); to prevent the program from closing, but make sure you add the Console.Read(); code before return statement, or else it will be a unreachable code .
Console.Read();
return 0;
check this Console.Read

Add The Read method to show the output.
Console.WriteLine("Hello, World!");
Console.Read();
return 0;

Here is a way to do it without involving Console:
var endlessTask = new TaskCompletionSource<bool>().Task;
endlessTask.Wait();

Tools -> Options -> Debugging -> General -> Automatically close the console (5th last option)
Check the box and close.
This applied to all projects.

The program is closing as soon as its execution is complete.
In this case when you return 0;. This is expected functionality.
If you want to see the output then either run it in a terminal manually or set a wait at the end of the program so that it will stay open for a few seconds (using the threading library).

Related

What is the Purpose of Console.WriteLine() in Winforms

I once saw the source code of a winform application and the code had a Console.WriteLine();. I asked the reason for that and i was told that it was for debugging purposes.
Pls what is the essence of Console.WriteLine(); in a winform and what action does it perform because when i tried using it, it never wrote anything.
It writes to the Console.
The end user won't see it, and to be honest its much cleaner to put it into a proper log, but if you run it through VS the Console window will populate.
Winforms are just console apps that show windows. You can direct your debug info to the console app.
As you can see in the below example there is a command that attaches the parent window then pumps info to it.
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace MyWinFormsApp
{
static class Program
{
[DllImport( "kernel32.dll" )]
static extern bool AttachConsole( int dwProcessId );
private const int ATTACH_PARENT_PROCESS = -1;
[STAThread]
static void Main( string[] args )
{
// redirect console output to parent process;
// must be before any calls to Console.WriteLine()
AttachConsole( ATTACH_PARENT_PROCESS );
// to demonstrate where the console output is going
int argCount = args == null ? 0 : args.Length;
Console.WriteLine( "nYou specified {0} arguments:", argCount );
for (int i = 0; i < argCount; i++)
{
Console.WriteLine( " {0}", args[i] );
}
// launch the WinForms application like normal
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault( false );
Application.Run( new Form1() );
}
}
}
Here is the resource for this example:http://www.csharp411.com/console-output-from-winforms-application/
You wouldn't really use it normally but if you've attached a Console or use AllocConsole, it will function like in any other console application and the output will be visible there.
For quick debugging, I prefer Debug.WriteLine but for a more robust solution, the Trace class may be preferable.
It wouldn't perform anything unless the Console was redirected to say the Output window. Really, they should be leveraging Debug.WriteLine instead.
The benefit of Debug.WriteLine is that it gets optimized away when building in Release mode.
NOTE: as pointed out by Brad Christie and Haedrian, apparently it will in fact write to the Console window in Visual Studio when running a Windows Forms application. You learn something new every day!

Console application closes immediately after opening in visual studio

I am trying to open a console application in visual studio built in C#. As soon as I open it, it closes immediately.
I know windows sets this is a a safety default (atleast I think). How do I fix this?
I know I can compile it and create a shortcut and modify the target so it has the location of the command prompt in it before the applications location. Although the programmer who created this has it generating information into the output of visual studio, so it's imperative that I only open it there.
It happens with most applications and not just in visual studio, just in this case I need it to open in VS 2010. I am using Windows 7.
This is an ancient problem and has inspired several funny cartoons:
Let's fix it. What you want to do is prompt the user to press the Any key when the console app was started from a shortcut on the desktop, Windows Explorer or Visual Studio. But not when it was started from the command processor running its own console. You can do so with a little pinvoke, you can find out if the process is the sole owner of the console window, like this:
using System;
class Program {
static void Main(string[] args) {
Console.WriteLine("Working on it...");
//...
Console.WriteLine("Done");
PressAnyKey();
}
private static void PressAnyKey() {
if (GetConsoleProcessList(new int[2], 2) <= 1) {
Console.Write("Press any key to continue");
Console.ReadKey();
}
}
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern int GetConsoleProcessList(int[] buffer, int size);
}
You can also run the application by pressing (Ctrl + F5) .. This will allow it to run in 'Release' mode, and by default, you will need to press 'return' to close the window.
Try adding Console.ReadKey(); at the end of Main() method. This is a quick and dirty way of stopping the window from closing by itself.
You need to wait for user input. Use either Console.ReadLine(), Console.Read(), or Console.ReadKey().
So, according to here
If your process is the only one attached to the console, then the
console will be destroyed when your process exits. If there are other
processes attached to the console, then the console will continue to
exist (because your program won’t be the last one).
And if we adapt the code to C# you would end up something like this:
using System;
using System.Runtime.InteropServices;
namespace CheckIfConsoleWillBeDestroyedAtTheEnd
{
internal class Program
{
private static void Main(string[] args)
{
// ...
if (ConsoleWillBeDestroyedAtTheEnd())
{
Console.WriteLine("Press any key to continue . . .");
Console.ReadKey();
}
}
private static bool ConsoleWillBeDestroyedAtTheEnd()
{
var processList = new uint[1];
var processCount = GetConsoleProcessList(processList, 1);
return processCount == 1;
}
[DllImport("kernel32.dll", SetLastError = true)]
static extern uint GetConsoleProcessList(uint[] processList, uint processCount);
}
}

C# Windows application that doesn't fork (or Console Application with no console window) [duplicate]

I want to make a C# program that can be run as a CLI or GUI application depending on what flags are passed into it. Can this be done?
I have found these related questions, but they don't exactly cover my situation:
How to write to the console in a GUI application
How do I get console output in C++ with a Windows program?
Jdigital's answer points to Raymond Chen's blog, which explains why you can't have an application that's both a console program and a non-console* program: The OS needs to know before the program starts running which subsystem to use. Once the program has started running, it's too late to go back and request the other mode.
Cade's answer points to an article about running a .Net WinForms application with a console. It uses the technique of calling AttachConsole after the program starts running. This has the effect of allowing the program to write back to the console window of the command prompt that started the program. But the comments in that article point out what I consider to be a fatal flaw: The child process doesn't really control the console. The console continues accepting input on behalf of the parent process, and the parent process is not aware that it should wait for the child to finish running before using the console for other things.
Chen's article points to an article by Junfeng Zhang that explains a couple of other techniques.
The first is what devenv uses. It works by actually having two programs. One is devenv.exe, which is the main GUI program, and the other is devenv.com, which handles console-mode tasks, but if it's used in a non-console-like manner, it forwards its tasks to devenv.exe and exits. The technique relies on the Win32 rule that com files get chosen ahead of exe files when you type a command without the file extension.
There's a simpler variation on this that the Windows Script Host does. It provides two completely separate binaries, wscript.exe and cscript.exe. Likewise, Java provides java.exe for console programs and javaw.exe for non-console programs.
Junfeng's second technique is what ildasm uses. He quotes the process that ildasm's author went through when making it run in both modes. Ultimately, here's what it does:
The program is marked as a console-mode binary, so it always starts out with a console. This allows input and output redirection to work as normal.
If the program has no console-mode command-line parameters, it re-launches itself.
It's not enough to simply call FreeConsole to make the first instance cease to be a console program. That's because the process that started the program, cmd.exe, "knows" that it started a console-mode program and is waiting for the program to stop running. Calling FreeConsole would make ildasm stop using the console, but it wouldn't make the parent process start using the console.
So the first instance restarts itself (with an extra command-line parameter, I suppose). When you call CreateProcess, there are two different flags to try, DETACHED_PROCESS and CREATE_NEW_CONSOLE, either of which will ensure that the second instance will not be attached to the parent console. After that, the first instance can terminate and allow the command prompt to resume processing commands.
The side effect of this technique is that when you start the program from a GUI interface, there will still be a console. It will flash on the screen momentarily and then disappear.
The part in Junfeng's article about using editbin to change the program's console-mode flag is a red herring, I think. Your compiler or development environment should provide a setting or option to control which kind of binary it creates. There should be no need to modify anything afterward.
The bottom line, then, is that you can either have two binaries, or you can have a momentary flicker of a console window. Once you decide which is the lesser evil, you have your choice of implementations.
* I say non-console instead of GUI because otherwise it's a false dichotomy. Just because a program doesn't have a console doesn't mean it has a GUI. A service application is a prime example. Also, a program can have a console and windows.
Check out Raymond's blog on this topic:
https://devblogs.microsoft.com/oldnewthing/20090101-00/?p=19643
His first sentence: "You can't, but you can try to fake it."
http://www.csharp411.com/console-output-from-winforms-application/
Just check the command line arguments before the WinForms Application. stuff.
I should add that in .NET it is RIDICULOUSLY easy to simply make a console and GUI projects in the same solution which share all their assemblies except main. And in this case, you could make the command line version simply launch the GUI version if it is launched with no parameters. You would get a flashing console.
There is an easy way to do what you want. I'm always using it when writing apps that should have both a CLI and a GUI. You have to set your "OutputType" to "ConsoleApplication" for this to work.
class Program {
[DllImport("kernel32.dll", EntryPoint = "GetConsoleWindow")]
private static extern IntPtr _GetConsoleWindow();
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args) {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
/*
* This works as following:
* First we look for command line parameters and if there are any of them present, we run the CLI version.
* If there are no parameters, we try to find out if we are run inside a console and if so, we spawn a new copy of ourselves without a console.
* If there is no console at all, we show the GUI.
* We make an exception if we find out, that we're running inside visual studio to allow for easier debugging the GUI part.
* This way we're both a CLI and a GUI.
*/
if (args != null && args.Length > 0) {
// execute CLI - at least this is what I call, passing the given args.
// Change this call to match your program.
CLI.ParseCommandLineArguments(args);
} else {
var consoleHandle = _GetConsoleWindow();
// run GUI
if (consoleHandle == IntPtr.Zero || AppDomain.CurrentDomain.FriendlyName.Contains(".vshost"))
// we either have no console window or we're started from within visual studio
// This is the form I usually run. Change it to match your code.
Application.Run(new MainForm());
else {
// we found a console attached to us, so restart ourselves without one
Process.Start(new ProcessStartInfo(Assembly.GetEntryAssembly().Location) {
CreateNoWindow = true,
UseShellExecute = false
});
}
}
}
I think the preferred technique is what Rob called the devenv technique of using two executables: a launcher ".com" and the original ".exe". This is not that tricky to use if you have the boilerplate code to work with (see below link).
The technique uses tricks to have that ".com" be a proxy for the stdin/stdout/stderr and launch the same-named .exe file. This give the behavior of allowing the program to preform in a command line mode when called form a console (potentially only when certain command-line arguments are detected) while still being able to launch as a GUI application free of a console.
I hosted a project called dualsubsystem on Google Code that updates an old codeguru solution of this technique and provides the source code and working example binaries.
Here is what I believe to be the simple .NET C# solution to the problem. Just to restate the problem, when you run the console "version" of the app from a command line with a switch, the console keeps waiting (it doesn't return to the command prompt and the process keeps running) even if you have an Environment.Exit(0) at the end of your code. To fix this, just before calling Environment.Exit(0), call this:
SendKeys.SendWait("{ENTER}");
Then the console gets the final Enter key it needs to return to the command prompt and the process ends. Note: Don't call SendKeys.Send(), or the app will crash.
It's still necessary to call AttachConsole() as mentioned in many posts, but with this I get no command window flicker when launching the WinForm version of the app.
Here's the entire code in a sample app I created (without the WinForms code):
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace ConsoleWriter
{
static class Program
{
[DllImport("kernel32.dll")]
private static extern bool AttachConsole(int dwProcessId);
private const int ATTACH_PARENT_PROCESS = -1;
[STAThread]
static void Main(string[] args)
{
if(args.Length > 0 && args[0].ToUpperInvariant() == "/NOGUI")
{
AttachConsole(ATTACH_PARENT_PROCESS);
Console.WriteLine(Environment.NewLine + "This line prints on console.");
Console.WriteLine("Exiting...");
SendKeys.SendWait("{ENTER}");
Environment.Exit(0);
}
else
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
}
Hope it helps someone from also spending days on this problem. Thanks for the hint go to #dantill.
/*
** dual.c Runs as both CONSOLE and GUI app in Windows.
**
** This solution is based on the "Momentary Flicker" solution that Robert Kennedy
** discusses in the highest-rated answer (as of Jan 2013), i.e. the one drawback
** is that the console window will briefly flash up when run as a GUI. If you
** want to avoid this, you can create a shortcut to the executable and tell the
** short cut to run minimized. That will minimize the console window (which then
** immediately quits), but not the GUI window. If you want the GUI window to
** also run minimized, you have to also put -minimized on the command line.
**
** Tested under MinGW: gcc -o dual.exe dual.c -lgdi32
**
*/
#include <windows.h>
#include <stdio.h>
static int my_win_main(HINSTANCE hInstance,int argc,char *argv[],int iCmdShow);
static LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam);
static int win_started_from_console(void);
static BOOL CALLBACK find_win_by_procid(HWND hwnd,LPARAM lp);
int main(int argc,char *argv[])
{
HINSTANCE hinst;
int i,gui,relaunch,minimized,started_from_console;
/*
** If not run from command-line, or if run with "-gui" option, then GUI mode
** Otherwise, CONSOLE app.
*/
started_from_console = win_started_from_console();
gui = !started_from_console;
relaunch=0;
minimized=0;
/*
** Check command options for forced GUI and/or re-launch
*/
for (i=1;i<argc;i++)
{
if (!strcmp(argv[i],"-minimized"))
minimized=1;
if (!strcmp(argv[i],"-gui"))
gui=1;
if (!strcmp(argv[i],"-gui-"))
gui=0;
if (!strcmp(argv[i],"-relaunch"))
relaunch=1;
}
if (!gui && !relaunch)
{
/* RUN AS CONSOLE APP */
printf("Console app only.\n");
printf("Usage: dual [-gui[-]] [-minimized].\n\n");
if (!started_from_console)
{
char buf[16];
printf("Press <Enter> to exit.\n");
fgets(buf,15,stdin);
}
return(0);
}
/* GUI mode */
/*
** If started from CONSOLE, but want to run in GUI mode, need to re-launch
** application to completely separate it from the console that started it.
**
** Technically, we don't have to re-launch if we are not started from
** a console to begin with, but by re-launching we can avoid the flicker of
** the console window when we start if we start from a shortcut which tells
** us to run minimized.
**
** If the user puts "-minimized" on the command-line, then there's
** no point to re-launching when double-clicked.
*/
if (!relaunch && (started_from_console || !minimized))
{
char exename[256];
char buf[512];
STARTUPINFO si;
PROCESS_INFORMATION pi;
GetStartupInfo(&si);
GetModuleFileNameA(NULL,exename,255);
sprintf(buf,"\"%s\" -relaunch",exename);
for (i=1;i<argc;i++)
{
if (strlen(argv[i])+3+strlen(buf) > 511)
break;
sprintf(&buf[strlen(buf)]," \"%s\"",argv[i]);
}
memset(&pi,0,sizeof(PROCESS_INFORMATION));
memset(&si,0,sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwX = 0; /* Ignored unless si.dwFlags |= STARTF_USEPOSITION */
si.dwY = 0;
si.dwXSize = 0; /* Ignored unless si.dwFlags |= STARTF_USESIZE */
si.dwYSize = 0;
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWNORMAL;
/*
** Note that launching ourselves from a console will NOT create new console.
*/
CreateProcess(exename,buf,0,0,1,DETACHED_PROCESS,0,NULL,&si,&pi);
return(10); /* Re-launched return code */
}
/*
** GUI code starts here
*/
hinst=GetModuleHandle(NULL);
/* Free the console that we started with */
FreeConsole();
/* GUI call with functionality of WinMain */
return(my_win_main(hinst,argc,argv,minimized ? SW_MINIMIZE : SW_SHOWNORMAL));
}
static int my_win_main(HINSTANCE hInstance,int argc,char *argv[],int iCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wndclass;
static char *wintitle="GUI Window";
wndclass.cbSize = sizeof (wndclass) ;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance;
wndclass.hIcon = NULL;
wndclass.hCursor = NULL;
wndclass.hbrBackground = NULL;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = wintitle;
wndclass.hIconSm = NULL;
RegisterClassEx (&wndclass) ;
hwnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,wintitle,0,
WS_VISIBLE|WS_OVERLAPPEDWINDOW,
100,100,400,200,NULL,NULL,hInstance,NULL);
SetWindowText(hwnd,wintitle);
ShowWindow(hwnd,iCmdShow);
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return(msg.wParam);
}
static LRESULT CALLBACK WndProc (HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam)
{
if (iMsg==WM_DESTROY)
{
PostQuitMessage(0);
return(0);
}
return(DefWindowProc(hwnd,iMsg,wParam,lParam));
}
static int fwbp_pid;
static int fwbp_count;
static int win_started_from_console(void)
{
fwbp_pid=GetCurrentProcessId();
if (fwbp_pid==0)
return(0);
fwbp_count=0;
EnumWindows((WNDENUMPROC)find_win_by_procid,0L);
return(fwbp_count==0);
}
static BOOL CALLBACK find_win_by_procid(HWND hwnd,LPARAM lp)
{
int pid;
GetWindowThreadProcessId(hwnd,(LPDWORD)&pid);
if (pid==fwbp_pid)
fwbp_count++;
return(TRUE);
}
I have written up an alternative approach which avoids the console flash. See How to create a Windows program that works both as a GUI and console application.
Run AllocConsole() in a static constructor works for me

Why is the console window closing immediately once displayed my output?

I'm studying C# by following the guides in MSDN.
Now, I just tried the Example 1 (here is the link to MSDN), and I've encountered an issue: why is the console window closing immediately once displayed my output?
using System;
public class Hello1
{
public static int Main()
{
Console.WriteLine("Hello, World!");
return 0;
}
}
the issue here is that their Hello World Program is showing up then it would immediately close.
why is that?
Because it's finished. When console applications have completed executing and return from their main method, the associated console window automatically closes. This is expected behavior.
If you want to keep it open for debugging purposes, you'll need to instruct the computer to wait for a key press before ending the app and closing the window.
The Console.ReadLine method is one way of doing that. Adding this line to the end of your code (just before the return statement) will cause the application to wait for you to press a key before exiting.
Alternatively, you could start the application without the debugger attached by pressing Ctrl+F5 from within the Visual Studio environment, but this has the obvious disadvantage of preventing you from using the debugging features, which you probably want at your disposal when writing an application.
The best compromise is probably to call the Console.ReadLine method only when debugging the application by wrapping it in a preprocessor directive. Something like:
#if DEBUG
Console.WriteLine("Press enter to close...");
Console.ReadLine();
#endif
You might also want the window to stay open if an uncaught exception was thrown. To do that you can put the Console.ReadLine(); in a finally block:
#if DEBUG
try
{
//...
}
finally
{
Console.WriteLine("Press enter to close...");
Console.ReadLine();
}
#endif
Instead of using
Console.Readline()
Console.Read()
Console.ReadKey()
you can run your program using Ctrl+F5 (if you are in Visual Studio). Then Visual Studio will keep the console window open, until you press a key.
Note: You cannot debug your code in this approach.
I assume the reason you don't want it to close in Debug mode, is because you want to look at the values of variables etc. So it's probably best to just insert a break-point on the closing "}" of the main function.
If you don't need to debug, then Ctrl-F5 is the best option.
This behaves the same for CtrlF5 or F5.
Place immediately before end of Main method.
using System.Diagnostics;
private static void Main(string[] args) {
DoWork();
if (Debugger.IsAttached) {
Console.WriteLine("Press any key to continue . . .");
Console.ReadKey();
}
}
In Visual Studio 2019 for .NET Core projects the console doesn't close automatically by default. You can configure the behaviour through menu Tools → Options → Debugging → General → Automatically close the console when debugging stops. If you get your console window automatically closing, check if the mentioned setting is not set.
The same applies to the .NET Framework new style console projects:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>
</Project>
The old style .NET Framework project still unconditionally close the console at the end (as of Visual Studio 16.0.1).
Reference: .NET Core tooling update for Visual Studio 2019 Preview 2
If you want to keep your application opened, you have to do something in order to keep its process alive. The below example is the simplest one, to be put at the end of your program:
while (true) ;
However, it'll cause the CPU to overload, as it's therefore forced to iterate infinitely.
At this point, you can opt to use System.Windows.Forms.Application class (but it requires you to add System.Windows.Forms reference):
Application.Run();
This doesn't leak CPU and works successfully.
In order to avoid to add System.Windows.Forms reference, you can use a simple trick, the so-called spin waiting, importing System.Threading:
SpinWait.SpinUntil(() => false);
This also works perfectly, and it basically consists of a while loop with a negated condition that is returned by the above lambda method. Why isn't this overloading CPU? You can look at the source code here; anyway, it basically waits some CPU cycle before iterating over.
You can also create a message looper, which peeks the pending messages from the system and processes each of them before passing to the next iteration, as follows:
[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "PeekMessage")]
public static extern int PeekMessage(out NativeMessage lpMsg, IntPtr hWnd, int wMsgFilterMin, int wMsgFilterMax, int wRemoveMsg);
[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "GetMessage")]
public static extern int GetMessage(out NativeMessage lpMsg, IntPtr hWnd, int wMsgFilterMin, int wMsgFilterMax);
[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "TranslateMessage")]
public static extern int TranslateMessage(ref NativeMessage lpMsg);
[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "DispatchMessage")]
public static extern int DispatchMessage(ref NativeMessage lpMsg);
[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode]
public static bool ProcessMessageOnce()
{
NativeMessage message = new NativeMessage();
if (!IsMessagePending(out message))
return true;
if (GetMessage(out message, IntPtr.Zero, 0, 0) == -1)
return true;
Message frameworkMessage = new Message()
{
HWnd = message.handle,
LParam = message.lParam,
WParam = message.wParam,
Msg = (int)message.msg
};
if (Application.FilterMessage(ref frameworkMessage))
return true;
TranslateMessage(ref message);
DispatchMessage(ref message);
return false;
}
Then, you can loop safely by doing something like this:
while (true)
ProcessMessageOnce();
The program immediately closes because there's nothing stopping it from closing. Insert a breakpoint at return 0; or add Console.Read(); before return 0; to prevent the program from closing.
Alternatively, you can delay the closing using the following code:
System.Threading.Thread.Sleep(1000);
Note the Sleep is using milliseconds.
Another way is to use Debugger.Break() before returning from Main method
The code is finished, to continue you need to add this:
Console.ReadLine();
or
Console.Read();
Use Console.Read(); to prevent the program from closing, but make sure you add the Console.Read(); code before return statement, or else it will be a unreachable code .
Console.Read();
return 0;
check this Console.Read
Add The Read method to show the output.
Console.WriteLine("Hello, World!");
Console.Read();
return 0;
Here is a way to do it without involving Console:
var endlessTask = new TaskCompletionSource<bool>().Task;
endlessTask.Wait();
Tools -> Options -> Debugging -> General -> Automatically close the console (5th last option)
Check the box and close.
This applied to all projects.
The program is closing as soon as its execution is complete.
In this case when you return 0;. This is expected functionality.
If you want to see the output then either run it in a terminal manually or set a wait at the end of the program so that it will stay open for a few seconds (using the threading library).

Can one executable be both a console and GUI application?

I want to make a C# program that can be run as a CLI or GUI application depending on what flags are passed into it. Can this be done?
I have found these related questions, but they don't exactly cover my situation:
How to write to the console in a GUI application
How do I get console output in C++ with a Windows program?
Jdigital's answer points to Raymond Chen's blog, which explains why you can't have an application that's both a console program and a non-console* program: The OS needs to know before the program starts running which subsystem to use. Once the program has started running, it's too late to go back and request the other mode.
Cade's answer points to an article about running a .Net WinForms application with a console. It uses the technique of calling AttachConsole after the program starts running. This has the effect of allowing the program to write back to the console window of the command prompt that started the program. But the comments in that article point out what I consider to be a fatal flaw: The child process doesn't really control the console. The console continues accepting input on behalf of the parent process, and the parent process is not aware that it should wait for the child to finish running before using the console for other things.
Chen's article points to an article by Junfeng Zhang that explains a couple of other techniques.
The first is what devenv uses. It works by actually having two programs. One is devenv.exe, which is the main GUI program, and the other is devenv.com, which handles console-mode tasks, but if it's used in a non-console-like manner, it forwards its tasks to devenv.exe and exits. The technique relies on the Win32 rule that com files get chosen ahead of exe files when you type a command without the file extension.
There's a simpler variation on this that the Windows Script Host does. It provides two completely separate binaries, wscript.exe and cscript.exe. Likewise, Java provides java.exe for console programs and javaw.exe for non-console programs.
Junfeng's second technique is what ildasm uses. He quotes the process that ildasm's author went through when making it run in both modes. Ultimately, here's what it does:
The program is marked as a console-mode binary, so it always starts out with a console. This allows input and output redirection to work as normal.
If the program has no console-mode command-line parameters, it re-launches itself.
It's not enough to simply call FreeConsole to make the first instance cease to be a console program. That's because the process that started the program, cmd.exe, "knows" that it started a console-mode program and is waiting for the program to stop running. Calling FreeConsole would make ildasm stop using the console, but it wouldn't make the parent process start using the console.
So the first instance restarts itself (with an extra command-line parameter, I suppose). When you call CreateProcess, there are two different flags to try, DETACHED_PROCESS and CREATE_NEW_CONSOLE, either of which will ensure that the second instance will not be attached to the parent console. After that, the first instance can terminate and allow the command prompt to resume processing commands.
The side effect of this technique is that when you start the program from a GUI interface, there will still be a console. It will flash on the screen momentarily and then disappear.
The part in Junfeng's article about using editbin to change the program's console-mode flag is a red herring, I think. Your compiler or development environment should provide a setting or option to control which kind of binary it creates. There should be no need to modify anything afterward.
The bottom line, then, is that you can either have two binaries, or you can have a momentary flicker of a console window. Once you decide which is the lesser evil, you have your choice of implementations.
* I say non-console instead of GUI because otherwise it's a false dichotomy. Just because a program doesn't have a console doesn't mean it has a GUI. A service application is a prime example. Also, a program can have a console and windows.
Check out Raymond's blog on this topic:
https://devblogs.microsoft.com/oldnewthing/20090101-00/?p=19643
His first sentence: "You can't, but you can try to fake it."
http://www.csharp411.com/console-output-from-winforms-application/
Just check the command line arguments before the WinForms Application. stuff.
I should add that in .NET it is RIDICULOUSLY easy to simply make a console and GUI projects in the same solution which share all their assemblies except main. And in this case, you could make the command line version simply launch the GUI version if it is launched with no parameters. You would get a flashing console.
There is an easy way to do what you want. I'm always using it when writing apps that should have both a CLI and a GUI. You have to set your "OutputType" to "ConsoleApplication" for this to work.
class Program {
[DllImport("kernel32.dll", EntryPoint = "GetConsoleWindow")]
private static extern IntPtr _GetConsoleWindow();
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args) {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
/*
* This works as following:
* First we look for command line parameters and if there are any of them present, we run the CLI version.
* If there are no parameters, we try to find out if we are run inside a console and if so, we spawn a new copy of ourselves without a console.
* If there is no console at all, we show the GUI.
* We make an exception if we find out, that we're running inside visual studio to allow for easier debugging the GUI part.
* This way we're both a CLI and a GUI.
*/
if (args != null && args.Length > 0) {
// execute CLI - at least this is what I call, passing the given args.
// Change this call to match your program.
CLI.ParseCommandLineArguments(args);
} else {
var consoleHandle = _GetConsoleWindow();
// run GUI
if (consoleHandle == IntPtr.Zero || AppDomain.CurrentDomain.FriendlyName.Contains(".vshost"))
// we either have no console window or we're started from within visual studio
// This is the form I usually run. Change it to match your code.
Application.Run(new MainForm());
else {
// we found a console attached to us, so restart ourselves without one
Process.Start(new ProcessStartInfo(Assembly.GetEntryAssembly().Location) {
CreateNoWindow = true,
UseShellExecute = false
});
}
}
}
I think the preferred technique is what Rob called the devenv technique of using two executables: a launcher ".com" and the original ".exe". This is not that tricky to use if you have the boilerplate code to work with (see below link).
The technique uses tricks to have that ".com" be a proxy for the stdin/stdout/stderr and launch the same-named .exe file. This give the behavior of allowing the program to preform in a command line mode when called form a console (potentially only when certain command-line arguments are detected) while still being able to launch as a GUI application free of a console.
I hosted a project called dualsubsystem on Google Code that updates an old codeguru solution of this technique and provides the source code and working example binaries.
Here is what I believe to be the simple .NET C# solution to the problem. Just to restate the problem, when you run the console "version" of the app from a command line with a switch, the console keeps waiting (it doesn't return to the command prompt and the process keeps running) even if you have an Environment.Exit(0) at the end of your code. To fix this, just before calling Environment.Exit(0), call this:
SendKeys.SendWait("{ENTER}");
Then the console gets the final Enter key it needs to return to the command prompt and the process ends. Note: Don't call SendKeys.Send(), or the app will crash.
It's still necessary to call AttachConsole() as mentioned in many posts, but with this I get no command window flicker when launching the WinForm version of the app.
Here's the entire code in a sample app I created (without the WinForms code):
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace ConsoleWriter
{
static class Program
{
[DllImport("kernel32.dll")]
private static extern bool AttachConsole(int dwProcessId);
private const int ATTACH_PARENT_PROCESS = -1;
[STAThread]
static void Main(string[] args)
{
if(args.Length > 0 && args[0].ToUpperInvariant() == "/NOGUI")
{
AttachConsole(ATTACH_PARENT_PROCESS);
Console.WriteLine(Environment.NewLine + "This line prints on console.");
Console.WriteLine("Exiting...");
SendKeys.SendWait("{ENTER}");
Environment.Exit(0);
}
else
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
}
Hope it helps someone from also spending days on this problem. Thanks for the hint go to #dantill.
/*
** dual.c Runs as both CONSOLE and GUI app in Windows.
**
** This solution is based on the "Momentary Flicker" solution that Robert Kennedy
** discusses in the highest-rated answer (as of Jan 2013), i.e. the one drawback
** is that the console window will briefly flash up when run as a GUI. If you
** want to avoid this, you can create a shortcut to the executable and tell the
** short cut to run minimized. That will minimize the console window (which then
** immediately quits), but not the GUI window. If you want the GUI window to
** also run minimized, you have to also put -minimized on the command line.
**
** Tested under MinGW: gcc -o dual.exe dual.c -lgdi32
**
*/
#include <windows.h>
#include <stdio.h>
static int my_win_main(HINSTANCE hInstance,int argc,char *argv[],int iCmdShow);
static LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam);
static int win_started_from_console(void);
static BOOL CALLBACK find_win_by_procid(HWND hwnd,LPARAM lp);
int main(int argc,char *argv[])
{
HINSTANCE hinst;
int i,gui,relaunch,minimized,started_from_console;
/*
** If not run from command-line, or if run with "-gui" option, then GUI mode
** Otherwise, CONSOLE app.
*/
started_from_console = win_started_from_console();
gui = !started_from_console;
relaunch=0;
minimized=0;
/*
** Check command options for forced GUI and/or re-launch
*/
for (i=1;i<argc;i++)
{
if (!strcmp(argv[i],"-minimized"))
minimized=1;
if (!strcmp(argv[i],"-gui"))
gui=1;
if (!strcmp(argv[i],"-gui-"))
gui=0;
if (!strcmp(argv[i],"-relaunch"))
relaunch=1;
}
if (!gui && !relaunch)
{
/* RUN AS CONSOLE APP */
printf("Console app only.\n");
printf("Usage: dual [-gui[-]] [-minimized].\n\n");
if (!started_from_console)
{
char buf[16];
printf("Press <Enter> to exit.\n");
fgets(buf,15,stdin);
}
return(0);
}
/* GUI mode */
/*
** If started from CONSOLE, but want to run in GUI mode, need to re-launch
** application to completely separate it from the console that started it.
**
** Technically, we don't have to re-launch if we are not started from
** a console to begin with, but by re-launching we can avoid the flicker of
** the console window when we start if we start from a shortcut which tells
** us to run minimized.
**
** If the user puts "-minimized" on the command-line, then there's
** no point to re-launching when double-clicked.
*/
if (!relaunch && (started_from_console || !minimized))
{
char exename[256];
char buf[512];
STARTUPINFO si;
PROCESS_INFORMATION pi;
GetStartupInfo(&si);
GetModuleFileNameA(NULL,exename,255);
sprintf(buf,"\"%s\" -relaunch",exename);
for (i=1;i<argc;i++)
{
if (strlen(argv[i])+3+strlen(buf) > 511)
break;
sprintf(&buf[strlen(buf)]," \"%s\"",argv[i]);
}
memset(&pi,0,sizeof(PROCESS_INFORMATION));
memset(&si,0,sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwX = 0; /* Ignored unless si.dwFlags |= STARTF_USEPOSITION */
si.dwY = 0;
si.dwXSize = 0; /* Ignored unless si.dwFlags |= STARTF_USESIZE */
si.dwYSize = 0;
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWNORMAL;
/*
** Note that launching ourselves from a console will NOT create new console.
*/
CreateProcess(exename,buf,0,0,1,DETACHED_PROCESS,0,NULL,&si,&pi);
return(10); /* Re-launched return code */
}
/*
** GUI code starts here
*/
hinst=GetModuleHandle(NULL);
/* Free the console that we started with */
FreeConsole();
/* GUI call with functionality of WinMain */
return(my_win_main(hinst,argc,argv,minimized ? SW_MINIMIZE : SW_SHOWNORMAL));
}
static int my_win_main(HINSTANCE hInstance,int argc,char *argv[],int iCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wndclass;
static char *wintitle="GUI Window";
wndclass.cbSize = sizeof (wndclass) ;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance;
wndclass.hIcon = NULL;
wndclass.hCursor = NULL;
wndclass.hbrBackground = NULL;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = wintitle;
wndclass.hIconSm = NULL;
RegisterClassEx (&wndclass) ;
hwnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,wintitle,0,
WS_VISIBLE|WS_OVERLAPPEDWINDOW,
100,100,400,200,NULL,NULL,hInstance,NULL);
SetWindowText(hwnd,wintitle);
ShowWindow(hwnd,iCmdShow);
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return(msg.wParam);
}
static LRESULT CALLBACK WndProc (HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam)
{
if (iMsg==WM_DESTROY)
{
PostQuitMessage(0);
return(0);
}
return(DefWindowProc(hwnd,iMsg,wParam,lParam));
}
static int fwbp_pid;
static int fwbp_count;
static int win_started_from_console(void)
{
fwbp_pid=GetCurrentProcessId();
if (fwbp_pid==0)
return(0);
fwbp_count=0;
EnumWindows((WNDENUMPROC)find_win_by_procid,0L);
return(fwbp_count==0);
}
static BOOL CALLBACK find_win_by_procid(HWND hwnd,LPARAM lp)
{
int pid;
GetWindowThreadProcessId(hwnd,(LPDWORD)&pid);
if (pid==fwbp_pid)
fwbp_count++;
return(TRUE);
}
I have written up an alternative approach which avoids the console flash. See How to create a Windows program that works both as a GUI and console application.
Run AllocConsole() in a static constructor works for me

Categories

Resources