Остановите приложение, когда пользователь инициирует операцию выхода из системы / выключения - PullRequest
1 голос
/ 08 ноября 2011

У меня есть это приложение (приложение Windows Form, написанное на Visual C ++) от моего коллеги, и я столкнулся с некоторыми серьезными проблемами.Приложение не является ни службой, ни обычным приложением, я имею в виду, что оно имеет графический интерфейс, но большую часть времени оно работает в фоновом режиме (оно должно реагировать как служба, но это не так).Это приложение не позволяет пользователю выйти из системы, и мне нужно это сделать.

Я знаю, что Windows отправляет сообщение WM_QUERYENDSESSION всем работающим приложениям, когда пользователь пытается выйти из системы.Я пытался перехватить это сообщение в моей функции WndProc() и принудительно убить приложение, но оно работает только один раз.Когда я снова вхожу в систему и пытаюсь выйти из системы, операция не прекращается, потому что мое приложение не закрывается.

Если я пытаюсь использовать событие SessionEnding, приложение помещается только в системный трей и остается тамбез выхода из системы, но я считаю, что это потому, что метод Form_Closing выполняет эту операцию вместо закрытия программы (это было требованием, и я не могу это изменить).

Возможно, еще одна полезная информация заключается в том, что приложениезапускается автоматически, потому что у него есть запись в реестре HKLM, и всегда есть 2 экземпляра этого приложения (один должен контролировать другой и перезапускать его в случае сбоя, но не в случае «ручного» выключения).

Любые предложения будут хорошо приняты.

Спасибо.

Ответы [ 3 ]

1 голос
/ 08 ноября 2011

SetConsoleCtrlHandler может предоставить решение, поскольку события генерируются, когда пользователь выходит из системы и когда система выключается.

1 голос
/ 08 ноября 2011

Да, эта проблема вызвана обработчиком формы FormClosing.Вы должны обратить внимание на причину закрытия и только отменить ее, когда пользователь закрывает окно.Как это:

    System::Void Form1_FormClosing(System::Object^  sender, System::Windows::Forms::FormClosingEventArgs^  e) {
        // Do this *only* when the user closes the window
        if (e->CloseReason == CloseReason::UserClosing) {
            e->Cancel = true;
            this->Hide();
            // etc...
        }
    }
0 голосов
/ 08 ноября 2011

Если у вас есть контроль над исходным кодом, переопределите второй (контроллер) экземпляр как настоящую службу Windows.Пусть этот монитор контролирует экземпляр графического интерфейса пользователя и выполняет необходимые управляющие действия в случае его сбоя или необходимости выключения.

Это дает вам бесплатно часть логики автоматического перезапуска , которую вы в настоящее время должны выполнять вручную, а также разрешить правильную обработку выключения через SERVICE_CONTROL_SHUTDOWN

...