我正在尝试使用C来捕获Windows Server 2008 64位系统上的注销事件。目前我正在使用此处所示的控制台注销事件代码:http://www.cplusplus.com/forum/beginner/1501/(Grey Wolf的第6次评论,他的第二个编码示例)将附在本文末尾。
此代码存在几个问题。当用户启动程序时,它可以独立运行。当我开始添加对某些专有代码的调用时,它会停止捕获注销事件。没有GUI代码,这是所有控制台。任何人都知道会阻止这种工作吗?看起来相当挑剔。
此外,如果程序在登录期间由另一个程序自动启动(在用户级别启动并且会话ID相同,就像您要双击.exe并自行激活它),它也无法捕获注销事件。任何想法都会很棒。
实施例: 如果用户手动启动,这可以很好地独立工作。
#include <windows.h>
#include <tchar.h>
#include <signal.h>
BOOL WINAPI ConsoleHandler(
DWORD dwCtrlType // control signal type
);
static int startup;
int main(int argc, char *argv[])
{
if (SetConsoleCtrlHandler( (PHANDLER_ROUTINE)ConsoleHandler,TRUE)==FALSE)
{
// unable to install handler...
// display message to the user
printf("Unable to install handler!\n");
return -1;
}
startup=1;
while(1)
{
}
}
BOOL WINAPI ConsoleHandler(DWORD CEvent)
{
char mesg[128];
static FILE * pFile;
char FileName[32] = "ControlHandle.txt";
if(startup) {
/* create the filename */
pFile = fopen(FileName, "at");
printf("creating a file\n");
fprintf(pFile, "This file contains the message when a control character is received.\n\n\n");
fclose(pFile);
startup=0;
}
switch(CEvent)
{
case CTRL_C_EVENT:
pFile = fopen(FileName, "at");
if(pFile > 0){
printf("Got File Handle");
}
fprintf( pFile,"in handler got an CTRL_C_EVENTevent\n" );
fclose(pFile);
break;
case CTRL_BREAK_EVENT:
pFile = fopen(FileName, "at");
fprintf( pFile,"in handler got an CTRL_BREAK_EVENTevent\n" );
fclose(pFile);
break;
case CTRL_CLOSE_EVENT:
pFile = fopen(FileName, "at");
fprintf( pFile,"in handler got an CTRL_CLOSE_EVENTevent\n" );
fclose(pFile);
break;
case CTRL_LOGOFF_EVENT:
pFile = fopen(FileName, "at");
fprintf( pFile,"in handler got an CTRL_LOGOFF_EVENTevent\n" );
fclose(pFile);
break;
case CTRL_SHUTDOWN_EVENT:
pFile = fopen(FileName, "at");
fprintf( pFile,"in handler got an CTRL_SHUTDOWN_EVENTevent\n" );
fclose(pFile);
break;
}
return TRUE;
}
答案 0 :(得分:0)
您可能必须将代码实现为服务,因为您希望程序一直运行到最后并从登录的最开始开始。这样,程序在系统模式下运行,并且当它开始强制用户级别(包括管理程序)时不会关闭yoru程序。
答案 1 :(得分:0)
您可以收听WM_QUERYENDSESSION或WM_ENDSESSION条消息。只要您有一个带有消息循环的窗口(不一定是可见的),这在GUI和控制台应用程序中都有效。
编辑:检查this thread,尤其是上一篇文章中的代码。
额外信息:
答案 2 :(得分:0)
有两种方式
如果您使用的是控制台应用程序,则可以使用
main()
{
...
SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlEventHandler, TRUE );
...
}
BOOL CtrlEventHandler(DWORD eventType)
{
if(eventType == CTRL_C_EVENT)
{
printf(""Sample text");
return FALSE
}
else if(eventType == CTRL_LOGOFF_EVENT)
{
printf(""Sample text");
return FALSE
}
}
如果您使用的是基于Windows UI的应用程序,那么您可以使用虚函数WindowProc并使用下面的代码
LRESULT CMainDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_ENDSESSION)
{
if(lParam == ENDSESSION_LOGOFF)
{
/*Handle event*/
}
}
return CDialogEx::WindowProc(message, wParam, lParam);
}
对于第一个选项,您可以使用This MSDN link