C
C#3mo ago
Loumos

Prevent the exit button from closing console application

So here is the situation i am dealing with. I have a Windows forms application that has the Application-Output type: set to Console Application. This allows the console and the windows forms app to be shown at execution. Now if the user presses the exit button on the console it will close the application. I am trying to change the behavior of this to only hide the console using the imported ShowWindow(IntPtr hWnd, int nCmdShow); method from "user23.dll". Everything i have tried just closes the application. See code below.
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Security.Policy;
using System.Threading;
using System.CodeDom;

namespace Loumker
{
public static class cc
{
[DllImport("kernel32.dll")]
public static extern IntPtr GetConsoleWindow(); // gets console window

[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); // shows the console window note: can also hide it.

[DllImport("kernel32.dll")]
private static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate handler, bool add); //sets the control handler for the console.

private delegate bool ConsoleCtrlDelegate(CtrlType ctrlType);

[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); //gets the systemMenu of the console window.
[DllImport("user32.dll")]
private static extern int GetMenuItemCount(IntPtr hMenu); //get the count of menu items.
[DllImport("user32.dll")]
private static extern int RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags); //removes the system menu from the window.

private const uint MF_BYPOSITION = 0x400; // constant button position.

private enum CtrlType : uint
{
CTRL_CLOSE_EVENT = 0x0002
}

public static List<string> Processes = new List<string>();

private static Random r = new Random();

public static void Open()
{
IntPtr consoleHandle = GetConsoleWindow();

DisableCloseButton(consoleHandle);

SetConsoleCtrlHandler(new ConsoleCtrlDelegate(ConsoleCtrlHandler), true);

ShowWindow(consoleHandle, 5);
}

public static void Close()
{
IntPtr conoleHandle = GetConsoleWindow();

ShowWindow(conoleHandle, 0);
}

private static bool ConsoleCtrlHandler(CtrlType ctrlType)
{
return true;
}

private static void DisableCloseButton(IntPtr cwindow)
{
IntPtr sysMenu = GetSystemMenu(cwindow, false);
int closeMenuIndex = GetMenuItemCount(sysMenu) - 1;
RemoveMenu(sysMenu, (uint)closeMenuIndex, MF_BYPOSITION);
}
}
}
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Security.Policy;
using System.Threading;
using System.CodeDom;

namespace Loumker
{
public static class cc
{
[DllImport("kernel32.dll")]
public static extern IntPtr GetConsoleWindow(); // gets console window

[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); // shows the console window note: can also hide it.

[DllImport("kernel32.dll")]
private static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate handler, bool add); //sets the control handler for the console.

private delegate bool ConsoleCtrlDelegate(CtrlType ctrlType);

[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); //gets the systemMenu of the console window.
[DllImport("user32.dll")]
private static extern int GetMenuItemCount(IntPtr hMenu); //get the count of menu items.
[DllImport("user32.dll")]
private static extern int RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags); //removes the system menu from the window.

private const uint MF_BYPOSITION = 0x400; // constant button position.

private enum CtrlType : uint
{
CTRL_CLOSE_EVENT = 0x0002
}

public static List<string> Processes = new List<string>();

private static Random r = new Random();

public static void Open()
{
IntPtr consoleHandle = GetConsoleWindow();

DisableCloseButton(consoleHandle);

SetConsoleCtrlHandler(new ConsoleCtrlDelegate(ConsoleCtrlHandler), true);

ShowWindow(consoleHandle, 5);
}

public static void Close()
{
IntPtr conoleHandle = GetConsoleWindow();

ShowWindow(conoleHandle, 0);
}

private static bool ConsoleCtrlHandler(CtrlType ctrlType)
{
return true;
}

private static void DisableCloseButton(IntPtr cwindow)
{
IntPtr sysMenu = GetSystemMenu(cwindow, false);
int closeMenuIndex = GetMenuItemCount(sysMenu) - 1;
RemoveMenu(sysMenu, (uint)closeMenuIndex, MF_BYPOSITION);
}
}
}
1 Reply
Loumos
Loumos3mo ago
Note: I have tried using event handlers to catch when the user presses the button and change it that way but it just pauses for about 4 seconds then closes the application. ok i found a solution where i grey out the exit button. although for this to work i must execute this code within the program class before the application runs the Form. Program.cs
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Loumker
{
internal static class Program
{

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
cc.ConsoleSetup();
Application.Run(new Starter());

}
}
}
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Loumker
{
internal static class Program
{

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
cc.ConsoleSetup();
Application.Run(new Starter());

}
}
}
New cc.cs
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Security.Policy;
using System.Threading;
using System.CodeDom;

namespace Loumker
{
public static class cc
{
[DllImport("kernel32.dll")]
public static extern IntPtr GetConsoleWindow(); // gets console window

[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); // shows the console window note: can also hide it.

[DllImport("kernel32.dll")]
private static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate handler, bool add); //sets the control handler for the console.

private delegate bool ConsoleCtrlDelegate(CtrlType ctrlType);

[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); //gets the systemMenu of the console window.
[DllImport("user32.dll")]
private static extern int GetMenuItemCount(IntPtr hMenu); //get the count of menu items.
[DllImport("user32.dll")]
private static extern int RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags); //removes the system menu from the window.

[DllImport("user32.dll")]
private static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnabledItem, uint uEnable);

private const uint MF_BYPOSITION = 0x400; // constant button position.

private enum CtrlType : uint
{
CTRL_CLOSE_EVENT = 0x0002
}

public static List<string> Processes = new List<string>();

private static Random r = new Random();

public static void ConsoleSetup()
{
IntPtr cWH = GetConsoleWindow();
IntPtr sMH = GetSystemMenu(cWH, false);
EnableMenuItem(sMH, 0xF060, 0x00000001);
}

public static void Open()
{
IntPtr consoleHandle = GetConsoleWindow();

//DisableCloseButton(consoleHandle);

SetConsoleCtrlHandler(new ConsoleCtrlDelegate(ConsoleCtrlHandler), true);

ShowWindow(consoleHandle, 5);
}

public static void Close()
{
IntPtr cosnoleHandle = GetConsoleWindow();

ShowWindow(cosnoleHandle, 0);
}

private static bool ConsoleCtrlHandler(CtrlType ctrlType)
{
return true;
}

private static void DisableCloseButton(IntPtr cwindow)
{
IntPtr sysMenu = GetSystemMenu(cwindow, false);
int closeMenuIndex = GetMenuItemCount(sysMenu) - 1;
RemoveMenu(sysMenu, (uint)closeMenuIndex, MF_BYPOSITION);
}
}
}
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Security.Policy;
using System.Threading;
using System.CodeDom;

namespace Loumker
{
public static class cc
{
[DllImport("kernel32.dll")]
public static extern IntPtr GetConsoleWindow(); // gets console window

[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); // shows the console window note: can also hide it.

[DllImport("kernel32.dll")]
private static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate handler, bool add); //sets the control handler for the console.

private delegate bool ConsoleCtrlDelegate(CtrlType ctrlType);

[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); //gets the systemMenu of the console window.
[DllImport("user32.dll")]
private static extern int GetMenuItemCount(IntPtr hMenu); //get the count of menu items.
[DllImport("user32.dll")]
private static extern int RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags); //removes the system menu from the window.

[DllImport("user32.dll")]
private static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnabledItem, uint uEnable);

private const uint MF_BYPOSITION = 0x400; // constant button position.

private enum CtrlType : uint
{
CTRL_CLOSE_EVENT = 0x0002
}

public static List<string> Processes = new List<string>();

private static Random r = new Random();

public static void ConsoleSetup()
{
IntPtr cWH = GetConsoleWindow();
IntPtr sMH = GetSystemMenu(cWH, false);
EnableMenuItem(sMH, 0xF060, 0x00000001);
}

public static void Open()
{
IntPtr consoleHandle = GetConsoleWindow();

//DisableCloseButton(consoleHandle);

SetConsoleCtrlHandler(new ConsoleCtrlDelegate(ConsoleCtrlHandler), true);

ShowWindow(consoleHandle, 5);
}

public static void Close()
{
IntPtr cosnoleHandle = GetConsoleWindow();

ShowWindow(cosnoleHandle, 0);
}

private static bool ConsoleCtrlHandler(CtrlType ctrlType)
{
return true;
}

private static void DisableCloseButton(IntPtr cwindow)
{
IntPtr sysMenu = GetSystemMenu(cwindow, false);
int closeMenuIndex = GetMenuItemCount(sysMenu) - 1;
RemoveMenu(sysMenu, (uint)closeMenuIndex, MF_BYPOSITION);
}
}
}
I will make a custom command for the console to hide it when needed. i guess its more of a workaround vs a solution but it will work.