Используйте ShutdownBlockRequestCreate в консольном приложении Win32 - PullRequest
2 голосов
/ 07 июля 2011

Как правильно блокировать преждевременное завершение консольного приложения Win32, работающего в Windows 7?

Когда появилась Vista, произошли изменения относительно того, как Завершение работы приложения . Вопреки поведению в XP, которое состояло в том, чтобы открывать пользовательский интерфейс, запрашивающий, хочет ли пользователь принудительно закрыть или нет, Windows Vista (и 7) завершает процесс, если ничего не делается программно, чтобы предотвратить это. Консольные приложения и приложения без видимого окна верхнего уровня также должны использовать новую функцию ShutdownBlockRequestCreate , чтобы указать причину, по которой Vista будет отображаться в пользовательском интерфейсе, который всплывает, или она все равно завершит работу программы через 5 секунд. *

Ниже приведена моя попытка использования функции ShutdownBlockRequestCreate в консольном приложении Win32; опция предварительно скомпилированного заголовка была удалена из проекта после создания мастером. Я получаю код ошибки 5, соответствующий ERROR_ACCESS_DENIED, всякий раз, когда я использую функцию. Это, по-видимому (в соответствии с Ссылка на отключение приложения ), поскольку я не вызываю функцию из того же потока, который использовался для создания окна (окна консоли).

#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 ]

2 голосов
/ 08 июля 2011

В качестве обходного пути, не могли бы вы создать окно только для сообщений при запуске и использовать ShutdownBlockReasonCreate в качестве дескриптора окна?

0 голосов
/ 08 июля 2011

Не имеет смысла передавать дескриптор окна консоли из консольной программы, потому что окно консоли принадлежит подсистеме CSRSS, а не вашей консольной программе.Кроме того, что если ваша консоль работает в полноэкранном текстовом режиме?Независимо от того, кому что принадлежит, теперь нет даже окна вокруг вашей консоли!

Позволит ли вам передать NULL hWnd?

РЕДАКТИРОВАТЬ: Хорошо, тогда что если ваша консольПрограмма создает свое собственное скрытое окно и использует это?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...