How to Use Win32 APIs to enumerate applicationsProgramWindows and processes
Http://www.vckbase.com/document/viewdoc? Id = 1482
Download source code
Top-level window of enumeration
Enumerate processes with toolhelp32 Library
Process enumeration using psapi
How to handle a 16-bit Process
One thing we often encounter when writing programs is to accurately list all running programs or processes in the system. Windows Task Manager is such a program. It not only lists running desktop applications, but also lists all running processes in the system. How can we implement such a task in a program? This topic is discussed in detail below.
Top-level window of enumeration
Enumeration top-level windows on the desktop may be easier than enumeration processes. You can use the enumwindows () function to enumerate top-level windows on the desktop. Do not use getwindow () to create a window list, because the complex parent-child and compatriot relationships (Z-order) between windows are prone to confusion and inaccurate enumeration results.
Enumwindows () has two parameters: one is the pointer to the callback function, and the other is the User-Defined lparam value. For each desktop window (or top-level window), it calls the callback function once. Then the callback function uses the window handle for some processing, such as adding it to the list. This method ensures that the enumerated results are not confused by the complex hierarchy of the window. Therefore, once the window handle is available, we can get the window title through getwindowtext.
Creating a system process list is a little more complex than an enumeration window. This is mainly because the API functions used are dependent on different Win32 operating systems. In Windows 9x, Windows ME, Windows 2000 Professional, and Windows XP, we can use the APIS function in the toolhelp32 library. However, in Windows NT, we must use the APIS function in the psapi library, which is part of the SDK. This article will discuss the implementation of all the above platforms. The example program will wrap the APIs in the above library so that the packaged function can support all Win32 operating systems.
Use toolhelp32 library to enumerate Processes
Toolhelp32 library functions are in kernel32.dll. They are all standard API functions. However, Windows NT 4.0 does not provide these functions.
The toolhelp32 library contains various functions that can be used to enumerate processes and threads in the system and obtain information about memory and modules. The enumerated process only needs to use the following functions: createconlhelp32snapshot (), process32first (), and process32next ().
The first step to use the toolhelp32 function is to use the createconlhelp32snapshot () function to create the system information "snapshot ". This function allows you to select the type of information stored in the snapshot. If you are only interested in process information, you only need to include the th32cs_snapprocess flag. The createconlhelp32snapshot () function returns a handle. After the call is completed, the handle must be passed to closehandle ().
Next, call the process32first function to obtain the process list from the snapshot, and then call process32next again until the function returns false. This will traverse the process list in the snapshot. Both functions contain two parameters: Snapshot handle and processentry32 structure.
After process32first or process32next is called, processentry32 contains the key information of a process in the system. The process ID is stored in the th32processid of this structure. This ID can be passed to the OpenProcess () API to obtain the handle of the process. The corresponding executable file name and its storage path are stored in the szexefile structure member. You can also find other useful information in this structure.
Note: Before calling process32first (), remember to set the dwsize Member of the processentry32 structure to sizeof (processentry32 ).
Use the psapi library to enumerate Processes
In Windows NT, use psapi functions to create a process list. These functions are in psapi. dll. This file is distributed along with the Platform SDK. You can download the latest version of Platform SDK from here:
The psapi. h and psapi. Lib files required for using this library are also in this platform SDK.
To use the functions in the psapi library, you must add psapi. lib to the Code project and include the psapi. h file in all the modules that call psapi. Remember to distribute psapi. dll along with the executable file because it is not distributed along with Windows NT. You can click here to download the distribution version of psapi. dll separately (you do not need to download the Platform SDK completely ).
Like toolhelp32, The psapi Library also contains a variety of useful functions. Due to space limitations, this article only discusses functions related to enumeration processes: enumprocesses (), enumprocessmodules (), getmodulefilenameex (), and getmodulebasename ().
The first step to create a process list is to call enumprocesses (). The declaration of this function is as follows:
Bool enumprocesses (DWORD * lpidprocess, dword cb, DWORD * cbneeded );
Enumprocesses () includes three parameters: DWORD-type array pointer lpidprocess; the size and size of the array CB; and a pointer to DWORD cbneeded, which receives the length of the returned data. DWORD array is used to save the currently running process IDs. Cbneeded returns the memory size used by the array. The following formula shows how many processes are returned: nreturned = cbneeded/sizeof (DWORD ).
Note: although the document names the returned DWORD "cbneeded", there is actually no way to know the size of the array to be uploaded. Enumprocesses () does not return an array value greater than that passed by the CB parameter in cbneeded. Result: The only way to ensure the success of the enumprocesses () function is to allocate a DWORD array. If the returned cbneeded is equal to CB, allocate a large array and keep trying until the cbneeded value is less than CB.
Now you get an array whose elements Save the ID of each process in the system. If you want to obtain the process name, you must first obtain a handle. To obtain the handle from the process ID, you must call OpenProcess ().
Once a handle is available, you need to obtain the first module of the process. Therefore, call the enumprocessmodules () API:
Enumprocessmodules (hprocess, & hmodule, sizeof (hmodule), & cbreturned );
After the call, the hmodule variable is saved as the first module in the process. Remember that a process has no name, but the first module of the process is the executable module of the process. Now you can use the module handle returned by hmodule to call the getmodulefilenameex () or getmodulebasename () API function to obtain the full path name, or only the name of the executable module of the process. Both functions have four parameters: Process Handle, module handle, buffer pointer of the returned name, and buffer size.
Repeat this call process with each process ID returned by the enumprocesses () API, you can create a list of Windows NT processes.
How to handle a 16-bit Process
In Windows 95, Windows 98, and Windows ME, toolhelp32 treats 16-bit programs equally, and they have their own process IDs like Win32 programs. However, this is not the case in Windows NT, Windows 2000, or Windows XP. In these operating systems, the 16-bit program runs in the so-called vdm (that is, DOS machine ).
To enumerate 16-bit programs in Windows NT, Windows 2000, and Windows XP, you must use a function named vdmenumtaskwowex. InSource codeThe module must contain vdmdbg. h, and the vdmdbg. Lib file must be linked to the project. Both files are in the Platform SDK. The declaration of this function is as follows:
Int winapi vdmenumtaskwowex (DWORD dwprocessid, taskenumprocex FP, lparam );
Dwprocessid is the 16-bit task process identifier to be enumerated in NTVDM. The FP parameter is a pointer to the callback enumeration function. The parameter lparam is a user-defined value and is passed to the enumeration function. Enumeration functions should be defined as follows:
Bool winapi enum16 (DWORD dwthreadid, word hmod16, word htask16, psz pszmodname, psz pszfilename, lparam lpuserdefined );
This function is called once for each 16-bit task running in the NTVDM process. The NTVDM process ID is passed into vdmenumtaskwowex (). If you want to continue enumeration, false is returned. If you want to terminate enumeration, true is returned. Note that this is relative to enumwindows.
The code examples included in this article encapsulate psapi and toolhelp32 into a function named enumprocs. This function works like enumwindows (). It has a pointer to the callback function and needs to be called repeatedly once for every process in the system. Another parameter is the User-Defined lparam. The declaration of this function is as follows:
Bool winapi enumprocs (procenumproc lpproc, lparam );
When using this function, you must declare the callback function as follows:
Bool callback proc (dword dw, word w16, lpcstr lpstr, lparam );
The DW parameter contains the id. "w16" is the task number of a 16-bit task. If it is a 32-bit process, it is 0 (always 0 in Windows 95). The lpstr parameter points to the file name, lparam is user-defined and needs to be passed into enumprocs ().
The enumprocs () function uses toolhelp32 and psapi through the display link, instead of the commonly used implicit link. The main purpose of this process is to enable code compatibility at the binary level and run on all Win32 operating system platforms.
- MSJ "under the hood" 1996/08 by pietrek, Matt.
- MSJ "under the hood" 1996/11 by pietrek, Matt.