2014-09-20 4 views
-2

Основные данные:«Перехват» Windows завершает работу и выполняет команду

Язык C++ (visual C++ 2013). моя программа - это приложение win32, многопоточное (3 потока), и для его разработки он работает как критический процесс (используя RtlSetProcessIsCritical, он выполняет эту работу). Я могу программно включать и выключать его (две функции, одна устанавливает текущий процесс на критический, второй превращает текущий процесс в некритический).

Если я просто нажимаю start -> выключает окна, система, очевидно, сбой с bsod, тот же bsod, который вы получаете, если вы вручную завершите критический процесс.

Как я могу обнаружить, когда окна закрываются/перезапускаются? поэтому я могу выполнить функцию «превратить в некритичную», что приведет к чистому отключению. :)

Один из потоков состоит из цикла, который запускается каждые 5 или 10 секунд, добавив, что обнаружение выключения Windows здесь является единственным жизнеспособным вариантом.

Я пробовал только одну вещь, WM_ENDSESSION, как показано здесь http://msdn.microsoft.com/en-us/library/aa376889%28v=VS.85%29.aspx. но он «не удается» обнаружить остановку os, и он заканчивается bsod.

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

изменить: почему downvote? я учился и хотел спросить о чем-то, что я не могу исправить.

Редактировать: не могли бы вы привести пример того, где/как добавить фактическую проверку сообщения в моем цикле? я не могу справиться с этим, у меня уже есть случай WM_QUERYENDSESSION в инструкции switch .. спасибо.

--------------- EDIT:

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

thread 1 
{ 
    functionx(); 
    functiony(); 
} 


thread 2 
{ 
    functionz(); 
    functionf(); 
} 


thread 3 
{ 
    for (;;) 
    { 
     functiong(); 
     functionh(); 
    } 
} 

int main() 
{ 
    thread 1; 
    thread 2; 
    thread 3; 
} 

для части Айв GetMessage использовал код здесь http://www.winprog.org/tutorial/window_click.html и повторно отрегулировать, чтобы соответствовать моим потребностям:

HWND hwnd; 
MSG Msg; 

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
    switch (msg) 
    { 
    case WM_QUERYENDSESSION: 
     function_to_turn_critical_process_OFF(); 
     return 0; 
     break; 

    case WM_ENDSESSION: 
     function_to_turn_critical_process_OFF(); 
     return 0; 
     break; 
    } 

    return 0; 
} 

петля сообщение:

ok, если я вставляю контур сообщения в main(), как первое, что выполнено, я запускаю проблему номер 1, GetMessage, похоже, переводит всю вещь в сон, поэтому моя программа даже не начинает делать свои вещи.

Если я вставляю петлю сообщений в main() в качестве последней выполняемой вещи (в потоке 3), я запускаю номер проблемы 2, так как поток 3 никогда не заканчивается (петли навсегда), цикл сообщений, вероятно, никогда не запускается. Кроме того, цикл потока 3 содержит немного спящего режима в течение нескольких секунд, ив попытался поместить туда цикл получения сообщения, но он не смог его поймать, я не могу удалить исходный код, не могу изменить петли или удалить небольшую функцию сна.

Если я вставляю петлю сообщения в цикл потока 3, он просто не обнаруживает WM_QUERYENDSESSION, и я заканчиваю работу BSOD на закрытых окнах, поэтому моя функция «turn critical off» не выполняется.

что я могу сделать?Google не помогает в этой конкретной вещи. Я знаю, что в простой программе, которую я предположил бы поставить цикл сообщений в основном, и он будет работать для последнего, но я собираюсь сделать гайки здесь, пытаясь найти место в моем коде для этого цикла сообщений.

любая помощь приветствуется ..

+0

Получаете ли вы какие-либо сообщения в своей цепочке сообщений? Ответ на сообщение WM_QUERY_ENDSESSION приведен ниже. Ваша основная программа должна создать окно, запустить рабочие потоки и затем выполнить цикл обработки сообщений. Когда вы обрабатываете WM_ENDSESSION, измените приоритет приложения и, возможно, сообщите, что потоки закончатся изящно (SetEvent или что-то подобное). – lordjeb

ответ

3

Есть два сообщения, окна отправить в приложение: WM_QUERY_ENDSESSION и WM_ENDSESSION

вы можете реагировать на них, покидающие приложение корректно.

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

В WM_QUERY_ENDSESSION система еще не выключена. Поэтому вы можете настроить свои настройки, а затем вернуть «Да, конечно!».

Смежные вопросы