Is there a way to show the console in a Windows application?
I want to do something like this:
static class Program
{
[STAThread]
static void Main(string[] args) {
bool consoleMode = Boolean.Parse(args[0]);
if (consoleMode) {
Console.WriteLine("consolemode started");
// ...
} else {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
There is a way to achieve this which is quite simple, but I wouldn't suggest it is a good approach for an app you are going to let other people see. But if you had some developer need to show the console and windows forms at the same time, it can be done quite easily.
This method also supports showing only the Console window, but does not support showing only the Windows Form - i.e. the Console will always be shown. You can only interact (i.e. receive data - Console.ReadLine()
, Console.Read()
) with the console window if you do not show the windows forms; output to Console - Console.WriteLine()
- works in both modes.
This is provided as is; no guarantees this won't do something horrible later on, but it does work.
Start from a standard Console Application.
Mark the Main
method as [STAThread]
Add a reference in your project to System.Windows.Forms
Add a Windows Form to your project.
Add the standard Windows start code to your Main
method:
You will have an application that shows the Console and optionally windows forms.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ConsoleApplication9 {
class Program {
[STAThread]
static void Main(string[] args) {
if (args.Length > 0 && args[0] == "console") {
Console.WriteLine("Hello world!");
Console.ReadLine();
}
else {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ConsoleApplication9 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void Form1_Click(object sender, EventArgs e) {
Console.WriteLine("Clicked");
}
}
}
As per Jeffrey Knight quote above, as soon as I run into situations where I need API calls to get something done, I tend to stop and ask myself "am I overcomplicating things?".
If what is wanted is to have some code and run it in Windows GUI mode or Console mode, consider moving the code used in both modes off to a code library DLL, and then having a Windows Forms application that uses that DLL, and a Console application that uses that DLL (i.e. if in Visual Studio you now have a three-project solution: library with the bulk of the code, GUI with just the Win Forms code, and Console with just your console code.)
What worked for me was to write a console app separately that did what I wanted it to do, compile it down to an exe, and then do Process.Start("MyConsoleapp.exe","Arguments")
In wind32, console-mode applications are a completely different beast from the usual message-queue-receiving applications. They are declared and compile differently. You might create an application which has both a console part and normal window and hide one or the other. But suspect you will find the whole thing a bit more work than you thought.
Check this source code out. All commented code – used to create a console in a Windows app. Uncommented – to hide the console in a console app. From here. (Previously here.) Project reg2run
.
// Copyright (C) 2005-2015 Alexander Batishchev (abatishchev at gmail.com)
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace Reg2Run
{
static class ManualConsole
{
#region DllImport
/*
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool AllocConsole();
*/
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
/*
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern IntPtr CreateFile([MarshalAs(UnmanagedType.LPStr)]string fileName, [MarshalAs(UnmanagedType.I4)]int desiredAccess, [MarshalAs(UnmanagedType.I4)]int shareMode, IntPtr securityAttributes, [MarshalAs(UnmanagedType.I4)]int creationDisposition, [MarshalAs(UnmanagedType.I4)]int flagsAndAttributes, IntPtr templateFile);
*/
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FreeConsole();
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern IntPtr GetStdHandle([MarshalAs(UnmanagedType.I4)]int nStdHandle);
/*
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetStdHandle(int nStdHandle, IntPtr handle);
*/
#endregion
#region Methods
/*
public static void Create()
{
var ptr = GetStdHandle(-11);
if (!AllocConsole())
{
throw new Win32Exception("AllocConsole");
}
ptr = CreateFile("CONOUT$", 0x40000000, 2, IntPtr.Zero, 3, 0, IntPtr.Zero);
if (!SetStdHandle(-11, ptr))
{
throw new Win32Exception("SetStdHandle");
}
var newOut = new StreamWriter(Console.OpenStandardOutput());
newOut.AutoFlush = true;
Console.SetOut(newOut);
Console.SetError(newOut);
}
*/
public static void Hide()
{
var ptr = GetStdHandle(-11);
if (!CloseHandle(ptr))
{
throw new Win32Exception();
}
ptr = IntPtr.Zero;
if (!FreeConsole())
{
throw new Win32Exception();
}
}
#endregion
}
}
Easiest way is to start a WinForms application, go to settings and change the type to a console application.
Check this source code out. All commented code – used to create a console in a Windows app. Uncommented – to hide the console in a console app. From here. (Previously here.) Project reg2run
.
// Copyright (C) 2005-2015 Alexander Batishchev (abatishchev at gmail.com)
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace Reg2Run
{
static class ManualConsole
{
#region DllImport
/*
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool AllocConsole();
*/
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
/*
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern IntPtr CreateFile([MarshalAs(UnmanagedType.LPStr)]string fileName, [MarshalAs(UnmanagedType.I4)]int desiredAccess, [MarshalAs(UnmanagedType.I4)]int shareMode, IntPtr securityAttributes, [MarshalAs(UnmanagedType.I4)]int creationDisposition, [MarshalAs(UnmanagedType.I4)]int flagsAndAttributes, IntPtr templateFile);
*/
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FreeConsole();
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern IntPtr GetStdHandle([MarshalAs(UnmanagedType.I4)]int nStdHandle);
/*
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetStdHandle(int nStdHandle, IntPtr handle);
*/
#endregion
#region Methods
/*
public static void Create()
{
var ptr = GetStdHandle(-11);
if (!AllocConsole())
{
throw new Win32Exception("AllocConsole");
}
ptr = CreateFile("CONOUT$", 0x40000000, 2, IntPtr.Zero, 3, 0, IntPtr.Zero);
if (!SetStdHandle(-11, ptr))
{
throw new Win32Exception("SetStdHandle");
}
var newOut = new StreamWriter(Console.OpenStandardOutput());
newOut.AutoFlush = true;
Console.SetOut(newOut);
Console.SetError(newOut);
}
*/
public static void Hide()
{
var ptr = GetStdHandle(-11);
if (!CloseHandle(ptr))
{
throw new Win32Exception();
}
ptr = IntPtr.Zero;
if (!FreeConsole())
{
throw new Win32Exception();
}
}
#endregion
}
}
And yet another belated answer.
I couldn't get any output to the console created with AllocConsole
as per earlier suggestions, so instead I'm starting with Console application. Then, if the console is not needed:
[DllImport("kernel32.dll")]
private static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
private const int SW_HIDE = 0;
private const int SW_SHOW = 5;
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
public static bool HideConsole()
{
var hwnd = GetConsoleWindow();
GetWindowThreadProcessId(hwnd, out var pid);
if (pid != Process.GetCurrentProcess().Id) // It's not our console - don't mess with it.
return false;
ShowWindow(hwnd, SW_HIDE);
return true;
}
There is a way to achieve this which is quite simple, but I wouldn't suggest it is a good approach for an app you are going to let other people see. But if you had some developer need to show the console and windows forms at the same time, it can be done quite easily.
This method also supports showing only the Console window, but does not support showing only the Windows Form - i.e. the Console will always be shown. You can only interact (i.e. receive data - Console.ReadLine()
, Console.Read()
) with the console window if you do not show the windows forms; output to Console - Console.WriteLine()
- works in both modes.
This is provided as is; no guarantees this won't do something horrible later on, but it does work.
Start from a standard Console Application.
Mark the Main
method as [STAThread]
Add a reference in your project to System.Windows.Forms
Add a Windows Form to your project.
Add the standard Windows start code to your Main
method:
You will have an application that shows the Console and optionally windows forms.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ConsoleApplication9 {
class Program {
[STAThread]
static void Main(string[] args) {
if (args.Length > 0 && args[0] == "console") {
Console.WriteLine("Hello world!");
Console.ReadLine();
}
else {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ConsoleApplication9 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void Form1_Click(object sender, EventArgs e) {
Console.WriteLine("Clicked");
}
}
}
In wind32, console-mode applications are a completely different beast from the usual message-queue-receiving applications. They are declared and compile differently. You might create an application which has both a console part and normal window and hide one or the other. But suspect you will find the whole thing a bit more work than you thought.
Actually AllocConsole with SetStdHandle in a GUI application might be a safer approach. The problem with the "console hijacking" already mentioned, is that the console might not be a foreground window at all, (esp. considering the influx of new window managers in Vista/Windows 7) among other things.
There is a way to achieve this which is quite simple, but I wouldn't suggest it is a good approach for an app you are going to let other people see. But if you had some developer need to show the console and windows forms at the same time, it can be done quite easily.
This method also supports showing only the Console window, but does not support showing only the Windows Form - i.e. the Console will always be shown. You can only interact (i.e. receive data - Console.ReadLine()
, Console.Read()
) with the console window if you do not show the windows forms; output to Console - Console.WriteLine()
- works in both modes.
This is provided as is; no guarantees this won't do something horrible later on, but it does work.
Start from a standard Console Application.
Mark the Main
method as [STAThread]
Add a reference in your project to System.Windows.Forms
Add a Windows Form to your project.
Add the standard Windows start code to your Main
method:
You will have an application that shows the Console and optionally windows forms.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ConsoleApplication9 {
class Program {
[STAThread]
static void Main(string[] args) {
if (args.Length > 0 && args[0] == "console") {
Console.WriteLine("Hello world!");
Console.ReadLine();
}
else {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ConsoleApplication9 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void Form1_Click(object sender, EventArgs e) {
Console.WriteLine("Clicked");
}
}
}
This is a tad old (OK, it's VERY old), but I'm doing the exact same thing right now. Here's a very simple solution that's working for me:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AllocConsole();
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
const int SW_HIDE = 0;
const int SW_SHOW = 5;
public static void ShowConsoleWindow()
{
var handle = GetConsoleWindow();
if (handle == IntPtr.Zero)
{
AllocConsole();
}
else
{
ShowWindow(handle, SW_SHOW);
}
}
public static void HideConsoleWindow()
{
var handle = GetConsoleWindow();
ShowWindow(handle, SW_HIDE);
}
Check this source code out. All commented code – used to create a console in a Windows app. Uncommented – to hide the console in a console app. From here. (Previously here.) Project reg2run
.
// Copyright (C) 2005-2015 Alexander Batishchev (abatishchev at gmail.com)
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace Reg2Run
{
static class ManualConsole
{
#region DllImport
/*
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool AllocConsole();
*/
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
/*
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern IntPtr CreateFile([MarshalAs(UnmanagedType.LPStr)]string fileName, [MarshalAs(UnmanagedType.I4)]int desiredAccess, [MarshalAs(UnmanagedType.I4)]int shareMode, IntPtr securityAttributes, [MarshalAs(UnmanagedType.I4)]int creationDisposition, [MarshalAs(UnmanagedType.I4)]int flagsAndAttributes, IntPtr templateFile);
*/
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FreeConsole();
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern IntPtr GetStdHandle([MarshalAs(UnmanagedType.I4)]int nStdHandle);
/*
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetStdHandle(int nStdHandle, IntPtr handle);
*/
#endregion
#region Methods
/*
public static void Create()
{
var ptr = GetStdHandle(-11);
if (!AllocConsole())
{
throw new Win32Exception("AllocConsole");
}
ptr = CreateFile("CONOUT$", 0x40000000, 2, IntPtr.Zero, 3, 0, IntPtr.Zero);
if (!SetStdHandle(-11, ptr))
{
throw new Win32Exception("SetStdHandle");
}
var newOut = new StreamWriter(Console.OpenStandardOutput());
newOut.AutoFlush = true;
Console.SetOut(newOut);
Console.SetError(newOut);
}
*/
public static void Hide()
{
var ptr = GetStdHandle(-11);
if (!CloseHandle(ptr))
{
throw new Win32Exception();
}
ptr = IntPtr.Zero;
if (!FreeConsole())
{
throw new Win32Exception();
}
}
#endregion
}
}
In wind32, console-mode applications are a completely different beast from the usual message-queue-receiving applications. They are declared and compile differently. You might create an application which has both a console part and normal window and hide one or the other. But suspect you will find the whole thing a bit more work than you thought.
Easiest way is to start a WinForms application, go to settings and change the type to a console application.
What worked for me was to write a console app separately that did what I wanted it to do, compile it down to an exe, and then do Process.Start("MyConsoleapp.exe","Arguments")
As per Jeffrey Knight quote above, as soon as I run into situations where I need API calls to get something done, I tend to stop and ask myself "am I overcomplicating things?".
If what is wanted is to have some code and run it in Windows GUI mode or Console mode, consider moving the code used in both modes off to a code library DLL, and then having a Windows Forms application that uses that DLL, and a Console application that uses that DLL (i.e. if in Visual Studio you now have a three-project solution: library with the bulk of the code, GUI with just the Win Forms code, and Console with just your console code.)
This is a tad old (OK, it's VERY old), but I'm doing the exact same thing right now. Here's a very simple solution that's working for me:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AllocConsole();
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
const int SW_HIDE = 0;
const int SW_SHOW = 5;
public static void ShowConsoleWindow()
{
var handle = GetConsoleWindow();
if (handle == IntPtr.Zero)
{
AllocConsole();
}
else
{
ShowWindow(handle, SW_SHOW);
}
}
public static void HideConsoleWindow()
{
var handle = GetConsoleWindow();
ShowWindow(handle, SW_HIDE);
}
There is a way to achieve this which is quite simple, but I wouldn't suggest it is a good approach for an app you are going to let other people see. But if you had some developer need to show the console and windows forms at the same time, it can be done quite easily.
This method also supports showing only the Console window, but does not support showing only the Windows Form - i.e. the Console will always be shown. You can only interact (i.e. receive data - Console.ReadLine()
, Console.Read()
) with the console window if you do not show the windows forms; output to Console - Console.WriteLine()
- works in both modes.
This is provided as is; no guarantees this won't do something horrible later on, but it does work.
Start from a standard Console Application.
Mark the Main
method as [STAThread]
Add a reference in your project to System.Windows.Forms
Add a Windows Form to your project.
Add the standard Windows start code to your Main
method:
You will have an application that shows the Console and optionally windows forms.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ConsoleApplication9 {
class Program {
[STAThread]
static void Main(string[] args) {
if (args.Length > 0 && args[0] == "console") {
Console.WriteLine("Hello world!");
Console.ReadLine();
}
else {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ConsoleApplication9 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void Form1_Click(object sender, EventArgs e) {
Console.WriteLine("Clicked");
}
}
}
Check this source code out. All commented code – used to create a console in a Windows app. Uncommented – to hide the console in a console app. From here. (Previously here.) Project reg2run
.
// Copyright (C) 2005-2015 Alexander Batishchev (abatishchev at gmail.com)
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace Reg2Run
{
static class ManualConsole
{
#region DllImport
/*
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool AllocConsole();
*/
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
/*
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern IntPtr CreateFile([MarshalAs(UnmanagedType.LPStr)]string fileName, [MarshalAs(UnmanagedType.I4)]int desiredAccess, [MarshalAs(UnmanagedType.I4)]int shareMode, IntPtr securityAttributes, [MarshalAs(UnmanagedType.I4)]int creationDisposition, [MarshalAs(UnmanagedType.I4)]int flagsAndAttributes, IntPtr templateFile);
*/
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FreeConsole();
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern IntPtr GetStdHandle([MarshalAs(UnmanagedType.I4)]int nStdHandle);
/*
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetStdHandle(int nStdHandle, IntPtr handle);
*/
#endregion
#region Methods
/*
public static void Create()
{
var ptr = GetStdHandle(-11);
if (!AllocConsole())
{
throw new Win32Exception("AllocConsole");
}
ptr = CreateFile("CONOUT$", 0x40000000, 2, IntPtr.Zero, 3, 0, IntPtr.Zero);
if (!SetStdHandle(-11, ptr))
{
throw new Win32Exception("SetStdHandle");
}
var newOut = new StreamWriter(Console.OpenStandardOutput());
newOut.AutoFlush = true;
Console.SetOut(newOut);
Console.SetError(newOut);
}
*/
public static void Hide()
{
var ptr = GetStdHandle(-11);
if (!CloseHandle(ptr))
{
throw new Win32Exception();
}
ptr = IntPtr.Zero;
if (!FreeConsole())
{
throw new Win32Exception();
}
}
#endregion
}
}
In wind32, console-mode applications are a completely different beast from the usual message-queue-receiving applications. They are declared and compile differently. You might create an application which has both a console part and normal window and hide one or the other. But suspect you will find the whole thing a bit more work than you thought.
Resurrecting a very old thread yet again, since none of the answers here worked very well for me.
I found a simple way that seems pretty robust and simple. It worked for me. The idea:
Example:
static class Program
{
[DllImport( "kernel32.dll", SetLastError = true )]
static extern bool AllocConsole();
[DllImport( "kernel32", SetLastError = true )]
static extern bool AttachConsole( int dwProcessId );
static void Main(string[] args)
{
bool consoleMode = Boolean.Parse(args[0]);
if (consoleMode)
{
if (!AttachConsole(-1))
AllocConsole();
Console.WriteLine("consolemode started");
// ...
}
else
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
A word of caution : it seems that if you try writing to the console prior to attaching or allocing a console, this approach doesn't work. My guess is the first time you call Console.Write/WriteLine, if there isn't already a console then Windows automatically creates a hidden console somewhere for you. (So perhaps Anthony's ShowConsoleWindow answer is better after you've already written to the console, and my answer is better if you've not yet written to the console). The important thing to note is that this doesn't work:
static void Main(string[] args)
{
Console.WriteLine("Welcome to the program"); //< this ruins everything
bool consoleMode = Boolean.Parse(args[0]);
if (consoleMode)
{
if (!AttachConsole(-1))
AllocConsole();
Console.WriteLine("consolemode started"); //< this doesn't get displayed on the parent console
// ...
}
else
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
Actually AllocConsole with SetStdHandle in a GUI application might be a safer approach. The problem with the "console hijacking" already mentioned, is that the console might not be a foreground window at all, (esp. considering the influx of new window managers in Vista/Windows 7) among other things.
And yet another belated answer.
I couldn't get any output to the console created with AllocConsole
as per earlier suggestions, so instead I'm starting with Console application. Then, if the console is not needed:
[DllImport("kernel32.dll")]
private static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
private const int SW_HIDE = 0;
private const int SW_SHOW = 5;
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
public static bool HideConsole()
{
var hwnd = GetConsoleWindow();
GetWindowThreadProcessId(hwnd, out var pid);
if (pid != Process.GetCurrentProcess().Id) // It's not our console - don't mess with it.
return false;
ShowWindow(hwnd, SW_HIDE);
return true;
}
Easiest way is to start a WinForms application, go to settings and change the type to a console application.
Source: Stackoverflow.com