Monitoring Open Programs Using Win32

I searched on the Internet and in various forums, but I can not find anything how to constantly monitor open programs, and then close another program (and not the one that is controlled) if something happens to the controlled program.

For example, let's say that there is already a Notepad window, and then a user or another program opens a Windows Explorer window. I want to know how to close the Notepad window without interacting with the Windows Explorer window (except that it is really open), and also close the Notepad window if the user closes the Windows Explorer window.

Thanks in advance !: D

+6
source share
4 answers

In windows, you can use the PSAPI (process state API) to know when processes start and end. The EnumProcesses function can provide you with this information.

A more reliable method for determining that a process has completed (since process identifiers can be reused) is to wait for its process descriptor (you will need SYNCHRONIZE authority), which you can obtain using OpenProcess and the process identifier obtained from EnumProcesses.

To terminate a process, there is always a TerminateProcess . To call TerminateProcess, you need a process handle with the PROCESS_TERMINATE permission. All of this assumes that you have the privileges necessary to complete these actions in the process that needs to be completed.

+7
source

One thing to be aware of is that processes and programs (or at least what the user sees as a program) are not necessarily the same thing.

If you use PSAPI to get a list of all running processes, you will see a lot of background process that does not correspond to the open window at all. There are also cases where one process can open several top-level windows. Therefore, when you have simple cases, such as Notepad, where once the notepad.exe process corresponds to one Notepad window, you also have cases such as:

  • A word in which one word processes all documents currently open (one process, many windows)
  • Explorer, where one exploere.exe process handles all open explorer windows, as well as things like control panel windows and taskbar windows.
  • Chrome (and other browsers) where each tab gets its own process (many processes, one window!)

Using TerminateProcess is probably not the best way to close the application: it is not equivalent to directly clicking the close button. He forcibly terminates the whole process there, and then, giving him no opportunity to clear. If you do this in Word when it restarts, it will go into "recovery mode" and will act as if it had not closed for the last time. This is best left as a last resort if the process stops responding. Also, if you terminate a process for a process such as Word or Explorer, you end up closing all windows that belong to that process, not just one specific one.

Given all this, if you want to essentially write some kind of program manager, you might be better off using a window-oriented approach rather than a process-oriented one. Instead of monitoring running processes, control top-level application windows.

There are several ways to listen for changes in windows; SetWinEventHook with EVENT_CREATE / DESTROY is one way to listen to HWNDs being created or destroyed (you will need to filter here, as it will tell you about all HWNDs - and much more!), But you only care about the top levels and only the applications). SetWindowsHookEx may have other options that may work here (WH_CBT). You can also use EnumWindows to display the currently present windows (again, you will need to filter your own dialogs and tooltips that are currently invisible to HWNDs, etc.).

Given HWND, you can get process information, if necessary, using GetWindowThreadProcessId.

To close the window by sending WM_SYSCOMMAND / SC_CLOSE it is best to try first: this is closer to pressing the close button, and this gives the application the ability to clear. Please note that in some applications the message "Are you sure you want to close?" if you have not saved recently - again, this is consistent with clicking the close button with the mouse.

+4
source

You need Microsoft PSAPI (Processes API), for example, to see open processes, you can use openProcess .

+1
source

The best known way to do this on Windows is to use the Process Status API . You can use this API to list processes. However, this API is annoying that it does not guarantee that you will receive a complete list or processes.

The best way to list processes is the Toolkit Tool Library , which includes a way to take a complete snapshot of all processes in the system at any given time.

+1
source

Source: https://habr.com/ru/post/897906/


All Articles