Мониторинг открытых программ с помощью Win32


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

Например, предположим, что уже открыто окно Блокнота, а затем пользователь или какая-либо другая программа открывает окно Проводника Windows. Я хочу знать, как закрыть окно Блокнота, не взаимодействуя с окном Проводника Windows (кроме понимая, что он действительно открыт), а также закрывает окно Блокнота, если пользователь закрывает окно Проводника Windows.

Заранее спасибо! :D

4 7

4 ответа:

В windows вы можете использовать PSAPI (Process Status API), чтобы узнать, когда процессы запускаются и завершаются. ФункцияEnumProcesses может дать вам эту информацию.

Более надежный способ определить, что процесс завершен (поскольку идентификаторы процессов могут быть использованы повторно), - это дождаться его дескриптора процесса (вам потребуется право доступа SYNCHRONIZE), которое вы можете получить с помощьюOpenProcess и идентификатора процесса, полученного из EnumProcesses.

Чтобы завершить a процесс, всегда естьTerminateProcess . Чтобы вызвать TerminateProcess, вам потребуется дескриптор процесса с правом доступа PROCESS_TERMINATE. Все это предполагает, что у вас есть права, необходимые для выполнения этих действий в процессе, который должен быть завершен.

Следует помнить, что процессы и программы - или, по крайней мере, то, что пользователь считает программой - не обязательно одно и то же.

Если вы используете PSAPI для получения списка всех запущенных процессов, вы увидите много фоновых процессов, которые вообще не соответствуют открытым окнам. Есть также случаи, когда один процесс может иметь несколько открытых окон верхнего уровня. Так что пока у вас есть простые случаи, как блокнот, где когда-то Блокнот.exe процесс соответствует одному Блокноту окно, у вас также есть случаи, как:

  • Word, где один процесс word обрабатывает все документы word, открытые в данный момент (один процесс, много окон)
  • исследователь, где один эксплуататор.процесс exe обрабатывает все открытые окна Проводника, а также такие вещи, как окна панели управления и панель задач.
  • Chrome (и другие браузеры), где каждая вкладка получает свой собственный процесс (много процессов, одно окно!)

Использование TerminateProcess, возможно, не лучший способ закрыть приложение: это не совсем то же самое, что нажать кнопку Закрыть. Он тут же насильственно прекращает весь процесс, не давая ему возможности очиститься. Если вы сделаете это в Word, когда он перезапустится, он перейдет в "режим восстановления" и будет действовать так, как будто он не закрылся полностью в прошлый раз. Его лучше оставить в качестве последнего средства, если процесс перестал отвечать на запросы. Кроме того, если вы завершите процесс на таком процессе, как Word или Explorer, вы в конечном итоге закроете все окна, принадлежащие этому процесс, а не только один конкретный.

Учитывая все это, если вы хотите по существу написать какой-то программный менеджер, вам, возможно, лучше использовать оконный подход, а не процессный. Вместо мониторинга запущенных процессов, контролируйте окна приложений верхнего уровня.

Существует несколько способов прослушивания изменений в windows; SetWinEventHook с EVENT_CREATE / DESTROY-это один из способов прослушивания создаваемых или уничтожаемых hwnd (вам потребуется выполнить фильтрацию вот, раз уж он расскажет вам обо всех hwnd - и не только! - но вы заботитесь только о топ-уровнях, и только о приложениях). SetWindowsHookEx может иметь другие параметры, которые могут работать здесь (WH_CBT). Вы также можете использовать EnumWindows для перечисления окон, присутствующих в данный момент (опять же, вам нужно будет отфильтровать принадлежащие диалоговые окна и всплывающие подсказки, в настоящее время невидимые hwnd и т. д.).

Учитывая HWND, вы можете получить информацию о процессе, если это необходимо, с помощью GetWindowThreadProcessId.

Чтобы закрыть окно, лучше всего сначала попробовать отправить WM_SYSCOMMAND/SC_CLOSE: это ближе к нажатию кнопки Закрыть, и это дает приложению шанс очистить. Обратите внимание, что некоторые приложения будут отображать " вы уверены, что хотите закрыть?"диалог, если вы не сохраняли в последнее время-опять же, это согласуется с нажатием кнопки закрыть с помощью мыши.

Самый известный способ сделать это в Windows-использовать Process Status API. Вы можете использовать этот API для перечисления процессов однако этот API раздражает тем, что он не гарантирует, что вы получите полный список или процессы.

Лучшим способом перечисления процессов является использование библиотекиTool Help Library , которая включает в себя способ сделать полныйснимок всех процессов в системе в любой момент времени.

Вам нужен Microsoft PSAPI (Processes API), например, чтобы увидеть открытые процессы, вы можете использовать функцию openProcess.