Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用C语言捕获Windows注销_C++_C_Windows_Winapi_Event Handling - Fatal编程技术网

C++ 用C语言捕获Windows注销

C++ 用C语言捕获Windows注销,c++,c,windows,winapi,event-handling,C++,C,Windows,Winapi,Event Handling,我正在尝试使用C捕获Windows Server 2008 64位系统上的注销事件。目前,我正在使用此处所示的控制台注销事件代码:(第六条评论,由灰太狼撰写,第二个编码示例)将附在本文末尾 这段代码有几个问题。当用户启动程序时,它可以独立运行。当我开始向一些专有代码添加调用时,它将停止捕获注销事件。没有GUI代码,这是所有控制台。有人知道有什么能阻止这一切的吗?这似乎很挑剔 此外,如果该程序在登录期间由另一个程序自动启动(在用户级别启动,会话ID与双击.exe并自己激活相同),则该程序也无法捕获

我正在尝试使用C捕获Windows Server 2008 64位系统上的注销事件。目前,我正在使用此处所示的控制台注销事件代码:(第六条评论,由灰太狼撰写,第二个编码示例)将附在本文末尾

这段代码有几个问题。当用户启动程序时,它可以独立运行。当我开始向一些专有代码添加调用时,它将停止捕获注销事件。没有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;
}
#包括
#包括
#包括
布尔WINAPI控制台句柄(
DWORD DWCTRL类型//控制信号类型
);
静态int启动;
int main(int argc,char*argv[])
{
if(SetConsoleCtrlHandler((PHANDLER_例程)ConsoleHandler,TRUE)=FALSE)
{
//无法安装处理程序。。。
//向用户显示消息
printf(“无法安装处理程序!\n”);
返回-1;
}
启动=1;
而(1)
{
}
}
布尔WINAPI控制台手柄(DWORD CEvent)
{
char-mesg[128];
静态文件*pFile;
char FileName[32]=“ControlHandle.txt”;
如果(启动){
/*创建文件名*/
pFile=fopen(文件名,“at”);
printf(“创建文件”);
fprintf(pFile,“此文件包含收到控制字符时的消息。\n\n\n”);
fclose(pFile);
启动=0;
}
开关(CEvent)
{
案例控制事件:
pFile=fopen(文件名,“at”);
如果(pFile>0){
printf(“获得文件句柄”);
}
fprintf(pFile,“in handler获得了一个CTRL_C_EVENTevent\n”);
fclose(pFile);
打破
案例控制中断事件:
pFile=fopen(文件名,“at”);
fprintf(pFile,“在处理程序中得到了一个CTRL\u BREAK\u EVENTevent\n”);
fclose(pFile);
打破
案例控制关闭事件:
pFile=fopen(文件名,“at”);
fprintf(pFile,“在处理程序中得到了一个CTRL\u CLOSE\u EVENTevent\n”);
fclose(pFile);
打破
案例控制\注销\事件:
pFile=fopen(文件名,“at”);
fprintf(pFile,“in handler获得了一个CTRL\u LOGOFF\u EVENTevent\n”);
fclose(pFile);
打破
案例控制关闭事件:
pFile=fopen(文件名,“at”);
fprintf(pFile,“在处理程序中得到了一个CTRL\u SHUTDOWN\u EVENTevent事件”);
fclose(pFile);
打破
}
返回TRUE;
}

您可能必须将代码作为一项服务来实现,因为您希望程序一直运行到登录的最后一刻,并在登录的最初一刻启动。这样,程序在系统模式下运行,当它开始强制用户级别(包括管理程序)时,不会关闭YRU程序

您可以收听广播或消息。这在GUI和控制台应用程序中都有效,只要您有一个带有消息循环的窗口(不必可见)

编辑:检查,尤其是上一篇文章中的代码

额外信息:

  • 有两种方法

    • 如果您使用的是控制台应用程序,那么您可以使用

      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);
      }
      
      对于第一个选项,您可以使用


    您是否已启用?可能会有用。当前目录如何?你应该先尝试使用一个绝对路径。Anisane-我不确定。我没有收到任何UAC通知,但系统在用户端被严重锁定。我目前正在使用一个管理员帐户。根据MSDN上的此()文档,注销事件仅适用于服务。交互进程将不会收到它。