首页
社区
课程
招聘
[讨论]控制台程序强制退出的问题
发表于: 2007-5-24 19:40 14617

[讨论]控制台程序强制退出的问题

2007-5-24 19:40
14617
一个永不退出的控制台程序,运行的时候可以关闭控制台窗口来强制结束它.
但奇怪的是该程序的C++对象都被正常地执行析构函数了.
关闭控制台窗口时,系统是怎样执行的呢?

补充一下:
该对象是全局的.
如果是从任务管理器中结束进程就不会被析构,
关闭窗口和任务管理器中结束任务就会被析构.

再给个例子程序供参考:
#include <stdio.h>
#include <windows.h>

class C
{
	FILE *fp;
public:
	C()
	{
		fp=fopen("test.txt","wb");
		fwrite("1",1,1,fp);
	}
	~C()
	{
		fwrite("2",1,1,fp);
		fclose(fp);
	}
};

C c;

int main()
{
	for(;;) Sleep(-1);
	//这个地方肯定没有被执行过
	return 0;
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (14)
雪    币: 288
活跃值: (112)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
2
关闭控制台窗口 类似 执行 Ctrl + C
可以试试,直接按 Ctrl + C
2007-5-24 20:18
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
個人臆測compiler生出的東西不同,我用一些compiler ,按ctrl-break destructor 也不會被invoke :< 

請問一下先進,standard c++ 中有規定這種行為嗎?
2007-5-25 02:36
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
NaX
4
我这里测试了一下,无论什么情况关闭都不会析构,并不存在你说的问题,奇怪!
2007-5-25 08:20
0
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
我用的编译器是VC6.0,难道这只是VC的特性,WinXP只照顾微软自己的编译器?
2007-5-25 08:51
0
雪    币: 305
活跃值: (36)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
6
怪事年年有,今年特别多!
2007-5-25 10:32
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
NaX
7
我也是用VC6.0
2007-5-25 10:50
0
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
我的环境是: WinXP+sp2,VC6.0+sp6

运行上面的例子程序(Release模式编译),直接关闭窗口的退出得到的文件内容是"12";
任务管理器中结束进程的方法得到的文件内容是"1".

我怀疑是一般的结束任务是先给程序发一个异常,程序处理异常时会析构全局对象,其他编译器可能不会处理这个异常.
2007-5-25 11:40
0
雪    币: 242
活跃值: (14)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
我的VS2005里也是只有“1”
在任务管理器“应用程序”那个里面“结束任务”时,程序接收到CTRL_CLOSE_EVENT
在任务管理器“进程”那个里面“结束进程”时,程序接直接被中止
点击“关闭”关闭控制台窗口的话,接收到CTRL_CLOSE_EVENT

建议您用SetConsoleCtrlHandler,看下您的程序
2007-5-26 02:52
0
雪    币: 242
活跃值: (14)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
或者你看下你编译的程序里CRT有没有调用SetConsoleCtrlHandler
2007-5-26 02:55
0
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
哦,我还忘了一点:

上面我的测试都是使用VC6的动态库,
如果使用静态库,则什么输出都没有,如果在fwrite后面加上fflush,则只得到"1"了.

也许VC2003/2005的动态库也可能输出"12".
2007-5-26 13:16
0
雪    币: 242
活跃值: (14)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
12
谢谢,学到了
2007-5-26 16:28
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
控制台程序运行完就自己退出
如何让它在自己输入某个命令后才退出?
2007-5-26 17:54
0
雪    币: 8213
活跃值: (3903)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
详情见WINAPI:
SetWinEventHook
WinEventProc

EVENT_CONSOLE_END_APPLICATION
0x4007

A console process has exited. The idObject parameter contains the process identifier of the terminated process.

2007-7-14 04:08
0
雪    币: 8213
活跃值: (3903)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
错了,应该是下面这样



#include <windows.h>
#include <stdio.h>

BOOL CtrlHandler( DWORD fdwCtrlType )
{
switch( fdwCtrlType )
{
// Handle the CTRL-C signal.
case CTRL_C_EVENT:
printf( "Ctrl-C event\n\n" );
Beep( 750, 300 );
return( TRUE );

// CTRL-CLOSE: confirm that the user wants to exit.
case CTRL_CLOSE_EVENT:
Beep( 600, 200 );
printf( "Ctrl-Close event\n\n" );
return( TRUE );

// Pass other signals to the next handler.
case CTRL_BREAK_EVENT:
Beep( 900, 200 );
printf( "Ctrl-Break event\n\n" );
return FALSE;

case CTRL_LOGOFF_EVENT:
Beep( 1000, 200 );
printf( "Ctrl-Logoff event\n\n" );
return FALSE;

case CTRL_SHUTDOWN_EVENT:
Beep( 750, 500 );
printf( "Ctrl-Shutdown event\n\n" );
return FALSE;

default:
return FALSE;
}
}

void main( void )
{
if( SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE ) )
{
printf( "\nThe Control Handler is installed.\n" );
printf( "\n -- Now try pressing Ctrl+C or Ctrl+Break, or" );
printf( "\n try logging off or closing the console...\n" );
printf( "\n(...waiting in a loop for events...)\n\n" );

while( 1 ){ }
}
else
printf( "\nERROR: Could not set control handler");
}

2007-7-14 04:13
0
游客
登录 | 注册 方可回帖
返回
//