After searching and reading the documentation for kernel32.dll
and making some tests
I reached to the following solution
I used this answer plus the function FreeConsole
from kernel32.dll
in order to make it work
First I made my WinForm application to run as a console application project properties > Application > Output type = Console Application
This will allow the project to run as a console application so when starting the application normally (double click exe or run from visual studio), it would start the windows application and would start a cmd window
To fix this I had to use the function FreeConsole
from kernel32.dll
in order to release the cmd window
The resulted working script I ended with is
static class Program
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool FreeConsole();
[STAThread]
static void Main(string[] args) {
if (args.Length == 0)
{
FreeConsole();
MessageBox.Show("Application running by double-clicking on exe");
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FrmMain());
}else
{
Console.WriteLine("Application is running from cmd with arguments);
}
}
}
EDIT The above snippet will remove the console windows from the application, which will release the handler of the Console
, meaning when calling Console.WriteLine
or Console.Write
functions it will throw an exception The handle is invalid
To avoid this problem, we don't need to release the console window completely, it is enough to hide it, as below using ShowWindow
from kernel32.dll
In the program
class
//[DllImport("kernel32.dll", SetLastError = true)]
//private static extern bool FreeConsole();
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
And in the Main
function
//FreeConsole();
var handle = GetConsoleWindow();
ShowWindow(handle, 0);