如何捕捉控制台程序的关闭事件

如何捕捉控制台程序的关闭事件,第1张

如何捕捉控制台程序的关闭事件 最近要做个控制台程序 在用户关闭程序的时候要做些处理 但控制台程序却没有WinForm的Closing或Closed事件 想想只能用API才捕捉消息来实现了 代码如下

using System;using System Windows Forms;using System Diagnostics;using System Runtime InteropServices;

namespace ConsoleColsed{

public delegate bool ConsoleCtrlDelegate(int dwCtrlType);

public class ClsMain {   [DllImport( kernel dll )] private static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine bool Add); //当用户关闭Console时 系统会发送次消息 private const int CTRL_CLOSE_EVENT = ;

[stathread] static void Main()  {  ClsMain cls=new ClsMain();       }   public ClsMain() {  // 用API安装事件处理  ConsoleCtrlDelegate newDelegate=new ConsoleCtrlDelegate(HandlerRoutine);               bool bRet=SetConsoleCtrlHandler(newDelegate true);  if(bRet==false)  //安装事件处理失败  {   Debug WriteLine( 失败 );  }  else  {   Console WriteLine( ok );   Console Read();  }         }   ///// <summary>   /// 处理消息的事件   /// </summary>   private static bool HandlerRoutine(int CtrlType)   { switch(CtrlType) {  case CTRL_CLOSE_EVENT:       //用户要关闭Console了   Debug WriteLine( Close );   break; }

lishixinzhi/Article/program/net/201311/11665

拦截WM_CLOSE也可以,但是要在系统里面安装一个hook,你可以查msdn找到和安装hook相关的windows

api函数

另外一个或许可行的简单方法是枚举窗口,找到窗口之后,更改窗口类型,改为没有关闭按钮的那种窗口。

没有退出,循环继续执行是因为IF判断中的代码没有被执行。

ConsoleWriteLine("\n继续运算吗(按Esc键退出)?");

ConsoleKey exitKey = new ConsoleKey();

exitKey = ConsoleReadKey()Key ;

if (exitKey == ConsoleKeyEscape)

{

ToBeContinue = false;

EnvironmentExit(0);

}

试试看能不能运行吧

不可以。控制台窗口不可关闭,否则Jmeter窗口自动关闭基本配置启动的时候不是中文我想很多朋友都很难过,其实是内置了中文的。要防止不小心点击到控制台窗口右上角的关闭按钮而导致程序非正常退出。

SetConsoleCtrlHandler( ) 函数可以设置一个自定义函数,当控制台发生某个特定的事件时,会自动调用你的自定义函数,比方说关闭控制台的时候,就会调用你的函数,相当于接收到了一个 WM_DESTROY 消息; BOOL WINAPI HandlerRoutine( DWORD dwCtrlType ){ if( CTRL_CLOSE_EVENT == dwCtrlType ){ // 控制台将要被关闭,这里添加你的处理代码 }}int main( int argc, char argv[ ] ){ SetConsoleCtrlHandler( HandlerRoutine, TRUE ); return 0;}

//调用系统API

        [DllImport("User32dll", EntryPoint = "FindWindow")]

        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32dll", EntryPoint = "GetSystemMenu")]

        static extern IntPtr GetSystemMenu(IntPtr hWnd, IntPtr bRevert);

        [DllImport("user32dll", EntryPoint = "RemoveMenu")]

        static extern IntPtr RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags);

        IntPtr windowHandle = FindWindow(null, "窗体名称可以自己设置");//例--

ConsoleTitle = "test";设置窗体名称test

            IntPtr closeMenu = GetSystemMenu(windowHandle, IntPtrZero);

            uint SC_CLOSE = 0xF060;

            RemoveMenu(closeMenu, SC_CLOSE, 0x0);//禁用关闭按钮

解决方法:

打开控制台后,用FindWindowA 找到新打开的控制台窗口, 并调用 RemoveMenu 将系统菜单中的 关闭菜单去掉

这样,用户就不能通过 该按钮或通过系统菜单关闭控制台了

在需要关闭控制台时,调用 FreeConsole 

//下面的函数供参考

BOOL  WINAPI DisableCloseMenu()

{

char oldTitle[100];

char newTitle[100];

GetConsoleTitleA(oldTitle ,100);

sprintf_s( newTitle,"%d-%d",GetTickCount(),GetCurrentProcessId());

SetConsoleTitleA(newTitle);

Sleep(100);

HWND hWnd =FindWindowA(NULL, newTitle);

SetConsoleTitleA(oldTitle);

if( hWnd )

{

HMENU h_Menu = GetSystemMenu( hWnd, FALSE);

if( h_Menu )

{

return RemoveMenu( h_Menu, 0xF060, 0);

//return ::EnableMenuItem( h_Menu, 0xF060, FALSE );

}

}

return FALSE;

}

以上就是关于如何捕捉控制台程序的关闭事件全部的内容,包括:如何捕捉控制台程序的关闭事件、如何通过 C 语言如何屏蔽控制台程序窗体的关闭按钮、C# 控制台程序按Esc键退出问题等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9511207.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-29
下一篇2023-04-29

发表评论

登录后才能评论

评论列表(0条)

    保存