在Win32控制台应用程序中使用ShutdownBlockRequestCreate

时间:2011-07-07 19:05:36

标签: c++ visual-c++ windows-7

阻止在Windows 7上运行的Win32控制台应用程序提前终止的正确方法是什么?

当Vista推出时,Application Shutdown的发生方式发生了变化。与XP中的行为相反,即打开一个UI,询问用户是否要强制关闭,如果没有以编程方式完成任何操作来阻止它,Windows Vista(和7)将终止该过程。没有可见顶级窗口的控制台应用程序和应用程序也必须使用新功能ShutdownBlockRequestCreate来提供Vista在弹出的UI中显示的原因,或者它将在5秒后终止程序。

以下是我在Win32控制台应用程序中使用ShutdownBlockRequestCreate函数的尝试;向导创建后,预编译的头选项已从项目中删除。每当我使用该函数时,我得到的错误代码为5,对应于ERROR_ACCESS_DENIED。这显然是(根据Application Shutdown link)因为我没有从用于创建窗口(控制台窗口)的相同线程调用该函数。

#include <iostream>
#include <tchar.h>
#include <conio.h>
#include <windows.h>

typedef BOOL (WINAPI *SBRCREATEFUNC)(HWND,LPCWSTR);

void RegisterShutdownBlockReason() {
    SBRCREATEFUNC ShutdownBlockReasonCreate;
    HWND hWnd = GetForegroundWindow();
    HINSTANCE hinstLib = LoadLibrary(TEXT("user32.dll"));
    if (hinstLib != NULL) {
        ShutdownBlockReasonCreate = (SBRCREATEFUNC) GetProcAddress(hinstLib,"ShutdownBlockReasonCreate");
        if(ShutdownBlockReasonCreate != NULL) {
          if(!(ShutdownBlockReasonCreate) (hWnd, L"Terminating Communication Sessions")) {
              printf("\nfailed To Register Reason, failure code: %d\n", GetLastError());
          } else {
              printf("\nRegistered Reason\n");
          }
        } else {
            printf("\nCouldn't load ShutdownBlockReasonCreate procedure\n");
        }
    } else {
        printf("\nFailed to LoadLibrary(\"user32.dll\")\n");
    }
}

int _tmain(int argc, _TCHAR* argv[]) {
    RegisterShutdownBlockReason();
    printf("Type to terminate program.\n");
    getch();
    return 0;
};

2 个答案:

答案 0 :(得分:2)

作为一种解决方法,您是否可以在启动时创建仅限消息的窗口并在其窗口句柄上使用ShutdownBlockReasonCreate

答案 1 :(得分:0)

从控制台程序传递控制台窗口句柄没有意义,因为控制台窗口归CSRSS子系统所有,而不是控制台程序。此外,如果您的控制台以全屏文本模式运行,该怎么办?无论谁拥有什么,现在你的控制台周围都没有窗户!

是否允许您通过NULL hWnd

编辑:那么,如果您的控制台程序创建了自己的隐藏窗口并使用它,该怎么办?