我有一个应用程序,我想在没有可见窗口或控制台的后台运行。为此,我创建了一个 Windows 应用程序,但我没有创建一个窗口。应用程序需要在请求关闭时(即用户注销时)进行一些清理。如何确定何时关闭?我可以简单地创建一个处理 WM_CLOSE 消息的消息循环吗?但是后来我没有 WndProc 来处理 WM_CLOSE 消息。
3 回答
不要为创建虚拟窗口而烦恼,有一种更简单的方法可以在无窗口应用程序中处理关闭/退出控制事件。为此,您使用一个鲜为人知的 Win API 函数,称为:SetConsoleCtrlHandler (...)
以下是如何使用控制处理程序的示例:
#include <windows.h>
// You can fill-in your own behavior, this is just an example handler that
// covers most of the most common events.
BOOL
ControlHandler (DWORD dwControlEvent)
{
switch (dwControlEvent)
{
// User wants to shutdown
case CTRL_SHUTDOWN_EVENT:
return FALSE;
// User wants to logoff
case CTRL_LOGOFF_EVENT:
return FALSE;
// Ctrl + C
case CTRL_C_EVENT:
return TRUE;
// User wants to exit the "normal" way
case CTRL_CLOSE_EVENT:
return TRUE;
// Everything else, just ignore it...
default:
return FALSE;
}
}
int
main (void)
{
// Set the control handler so the app will be notified upon any special
// termination event.
SetConsoleCtrlHandler ((PHANDLER_ROUTINE) ControlHandler, TRUE);
//
// Main Loop Here ...
//
return 0;
}
几年前我不得不了解这一点,因为当我的控制台应用程序以Ctrl + C. 我在查看堆栈跟踪时偶然发现了它。值得一提的是,这取代了事件的标准信号处理程序,例如Ctrl + C.
顺便说一句,即使它被称为“控制台控制处理程序”,它在使用WinMain (...)
而不是main (...)
.
要创建在后台运行的应用程序,请创建服务。服务可以响应ServiceMain
调用。
如果您坚持创建前端应用程序,那么应用程序尝试隐藏其主窗口基本上没有正当理由。您的可执行映像可以是 GUI ( IMAGE_SUBSYSTEM_WINDOWS_GUI
) 或控制台 ( IMAGE_SUBSYSTEM_WINDOWS_CUI
),您不能混合使用它们,请参阅如何编写可以作为控制台或 GUI 应用程序运行的程序。如果您选择 GUI 应用程序,那么您应该创建一个消息泵。您可以选择创建一个隐藏窗口作为您的“主”窗口。您将在这个隐藏的窗口中获得WM_QUERYENDSESSION
和WM_ENDSESSION
(这是您感兴趣的消息,而不是WM_CLOSE
)。
另一方面,控制台应用程序必须处理信号,就像 Andon 已经向您展示的那样。
选择你的毒药。我强烈建议走服务路线,因为这是“后台”应用程序的正确途径。