如何让控制台程序正常退出(2007-12-31 15:41:32)
标签:编程 控制台 退出 分类:编程
控制台程序通常是顺序执行一段指令后退出,但有时我们希望里面加入while循环语句完成持久的任务,如果不对控制台关闭的消息进行截获我们就不能保证程序的正常退出(通常是系统弹出窗口可以立即结束)。下面的示例是我在一个工程中使用的。
// BS.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "BS.h"
#include ".\\BSWorkerCenter.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 唯一的应用程序对象
CWinApp theApp;
using namespace std;
//控制台退出信号量
HANDLE g_hConsoleQuitEvent;
BOOL WINAPI HandlerRoutine(
DWORD dwCtrlType // control signal type
);
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// 初始化 MFC 并在失败时显示错误
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T("致命错误: MFC 初始化失败\n"));
nRetCode = 1;
}
else
{
// TODO: 在此处为应用程序的行为编写代码。
if( SetConsoleCtrlHandler(HandlerRoutine, TRUE))
{
//创建信号量
g_hConsoleQuitEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
//创建工作对象
CBSWorkerCenter* pCenter = CBSWorkerCenter::Instance();
//启动
_tprintf(_T("正在启动,请稍候...\n"));
pCenter->Start();//里面有很多线程在工作
//等待程序退出
::WaitForSingleObject(g_hConsoleQuitEvent, INFINITE);
//结束
system("cls");
_tprintf(_T("正在退出...请耐心等待几秒钟\n"));
pCenter->Stop();
//删除工作对象
delete pCenter;
//关闭信号量
::CloseHandle(g_hConsoleQuitEvent);
}
}
return nRetCode;
}
//回调函数
BOOL WINAPI HandlerRoutine(
DWORD dwCtrlType // control signal type
)
{
switch(dwCtrlType)
{
case CTRL_C_EVENT:
break;
case CTRL_BREAK_EVENT:
break;
case CTRL_CLOSE_EVENT:
::SetEvent(g_hConsoleQuitEvent);
break;
case CTRL_LOGOFF_EVENT:
::SetEvent(g_hConsoleQuitEvent);
break;
case CTRL_SHUTDOWN_EVENT:
::SetEvent(g_hConsoleQuitEvent);
break;
}
return TRUE;
}
标签:编程 控制台 退出 分类:编程
控制台程序通常是顺序执行一段指令后退出,但有时我们希望里面加入while循环语句完成持久的任务,如果不对控制台关闭的消息进行截获我们就不能保证程序的正常退出(通常是系统弹出窗口可以立即结束)。下面的示例是我在一个工程中使用的。
// BS.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "BS.h"
#include ".\\BSWorkerCenter.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 唯一的应用程序对象
CWinApp theApp;
using namespace std;
//控制台退出信号量
HANDLE g_hConsoleQuitEvent;
BOOL WINAPI HandlerRoutine(
DWORD dwCtrlType // control signal type
);
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// 初始化 MFC 并在失败时显示错误
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T("致命错误: MFC 初始化失败\n"));
nRetCode = 1;
}
else
{
// TODO: 在此处为应用程序的行为编写代码。
if( SetConsoleCtrlHandler(HandlerRoutine, TRUE))
{
//创建信号量
g_hConsoleQuitEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
//创建工作对象
CBSWorkerCenter* pCenter = CBSWorkerCenter::Instance();
//启动
_tprintf(_T("正在启动,请稍候...\n"));
pCenter->Start();//里面有很多线程在工作
//等待程序退出
::WaitForSingleObject(g_hConsoleQuitEvent, INFINITE);
//结束
system("cls");
_tprintf(_T("正在退出...请耐心等待几秒钟\n"));
pCenter->Stop();
//删除工作对象
delete pCenter;
//关闭信号量
::CloseHandle(g_hConsoleQuitEvent);
}
}
return nRetCode;
}
//回调函数
BOOL WINAPI HandlerRoutine(
DWORD dwCtrlType // control signal type
)
{
switch(dwCtrlType)
{
case CTRL_C_EVENT:
break;
case CTRL_BREAK_EVENT:
break;
case CTRL_CLOSE_EVENT:
::SetEvent(g_hConsoleQuitEvent);
break;
case CTRL_LOGOFF_EVENT:
::SetEvent(g_hConsoleQuitEvent);
break;
case CTRL_SHUTDOWN_EVENT:
::SetEvent(g_hConsoleQuitEvent);
break;
}
return TRUE;
}