Use ShutdownBlockRequestCreate in Win32 Console application

家住魔仙堡 提交于 2019-12-24 00:03:06

问题


What is the proper method of blocking premature termination of a Win32 Console Application running on Windows 7?

When Vista was introduced, there were changes regarding how Application Shutdown happened. Contrary to the behavior in XP, which was to open up a UI requesting whether the user wants to force close or not, Windows Vista (and 7) terminates the process if nothing is done programmatically to prevent it. Console apps and applications without a top level window visible must also use the new function ShutdownBlockRequestCreate to provide a reason for Vista to show in the UI that pops up or it will terminate the program after 5 seconds anyway.

Below is my attempt at using the ShutdownBlockRequestCreate function in a Win32 Console application; the precompiled header option was removed from the project after creation by the wizard. I get the error code of 5, corresponding to ERROR_ACCESS_DENIED, whenever I use the function. This is apparently (according to the Application Shutdown link) because I am not calling the function from the same thread as was used to create the window (the console window).

#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;
};

回答1:


As a workaround, could you create a message-only window at startup and use ShutdownBlockReasonCreate on its window handle?




回答2:


It doesn't make sense to pass the console window handle from a console program because the console window is owned by the CSRSS subsystem, not your console program. Furthermore, what if your console is run in full-screen text mode? Regardless of who owns what, now there's not even a window around your console!

Will it let you pass a NULL hWnd?

EDIT: Okay then, what if your console program creates its own hidden window and uses that?



来源:https://stackoverflow.com/questions/6615751/use-shutdownblockrequestcreate-in-win32-console-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!