[Webinar] Streamline your web hosting managementRegister Today

x
?
Solved

Finding instances of applications on a system ?

Posted on 1999-11-14
2
Medium Priority
?
264 Views
Last Modified: 2008-03-06
At a given point of time how to find
all the running instances of various applications on a system under windows (32 bit).
What API functions get called when alt+tab key sequence is pressed.
Could i get a psuedo code ???
0
Comment
Question by:pratish
2 Comments
 
LVL 1

Expert Comment

by:bhat
ID: 2206381
Get the desktopwindow and enum all children.

When Alt-tab is proessed WM_SYSKEYDOWN message is generated.
0
 
LVL 22

Accepted Solution

by:
nietod earned 40 total points
ID: 2206400
From

http://support.microsoft.com/support/kb/articles/q175/0/30.asp


*******************************************
SUMMARY

  One common programming problem in Win32 is the need to enumerate all "applications". The Task
  Manager under Windows NT 4.0 is a perfect example of this. It lists "applications" in two ways. The first
  tab of the Task Manager lists all "application windows" on the desktop. The second tab of the Task
  Manager lists all the "processes" in the system. This article provides details on how to perform both these
  tasks in Windows 95 and Windows NT.


  MORE INFORMATION

  Enumerating Top-Level Windows

  If you compare enumerating processes and enumerating top-level windows on the desktop, enumerating
  top-level windows is probably easier. To enumerate top-level windows under both Windows NT and
  Windows 95 platforms, use the EnumWindows() function. Do not use GetWindow() to create your list of
  windows, as it can be confused by z-order changes and lost windows.

  EnumWindows() takes a pointer to a callback function and a user-defined LPARAM value as its
  parameters. It calls the callback function once per window on the screen (or top-level window). The
  callback function can then do some processing with this window handle, such as add it to a list. This
  method is guaranteed not to be confused by changes in window's z-order, etc. Once you have a window
  handle, you can get its title by calling GetWindowText().

  Enumerating Processes

  Creating a list of processes in the system is a little more complex than enumerating windows. This is
  primarily due to the fact that the API functions for doing this are completely different under Windows 95
  and Windows NT. Under Windows 95, you must use functions from the ToolHelp32 group of APIs. Under
  Windows NT, you use functions from PSAPI.DLL, which is available in the Platform SDK. This article will
  discuss both of these techniques and also provide a sample wrapper function called "EnumProcs()" that
  works under Windows NT and Windows 95.

  Windows 95 and ToolHelp32:

  First let's go through the ToolHelp32 approach under Windows 95. The ToolHelp32 functions that reside in
  the KERNEL32.DLL are standard API functions available only under Windows 95. ToolHlp32 offers a variety
  of functions that allow you to enumerate processes and threads in the system, as well as get memory
  and module information. However, the following three functions are only needed when enumerating
  processes:

      CreateToolhelp32Snapshot(), Process32First(), and Process32Next().

  The first step in using the ToolHelp32 functions is to create a "snapshot" of the information in the
  system. You do this using the CreateToolhelp32Snapshot() function. This function allows you to choose
  what type of information is stored in the snapshot. Make sure you include the TH32CS_SNAPPROCESS flag
  if you are interested in process information. This function returns a HANDLE, and it is important to
  remember to pass the handle to CloseHandle() after you are finished with it.

  Next, to retrieve a list of processes from the snapshot you will call Process32First once, followed by
  repeated calls to Process32Next. Do this until one of these functions returns FALSE to iterate through the
  list of processes in the snapshot. Both of these functions take the handle to the snapshot, and a pointer
  to a PROCESSENTRY32 structure as their parameters.

  After a call to Process32First or Process32Next, the PROCESSENTRY32 structure will contain useful
  information about one of the processes in the system. The process ID is in the th32ProcessID member of
  the struct. This can be passed to the OpenProcess() API to get a handle to the process. The process'
  executable file and path are stored in the szExeFile member of the structure. Other useful information is
  also available in this structure.

  NOTE: It is important to remember to set the dwSize member to sizeof(PROCESSENTRY32) before calling
  Process32First().

  Windows NT and the PSAPI.DLL:

  The Windows NT approach to creating a list of processes uses functions from the PSAPI.DLL. The
  PSAPI.DLL file is distributed with the Platform SDK, which is available at
  http://www.microsoft.com/msdn/sdk (path: \MSSDK\bin\winnt\psapi.dll). The PSAPI.H and PSAPI.LIB files
  that you need are also included with the Platform SDK (paths:
  \Mssdk\samples\sdktools\image\winnt\pfmon\psapi.h and
  \Mssdk\samples\sdktools\image\winnt\pfmon\psapi.lib).

  To use the functions in the PSAPI.DLL, add the PSAPI.LIB file to your project, and include the PSAPI.H file
  with any modules that call the PSAPI.DLL functions. Remember to distribute the PSAPI.DLL file with any
  executable that uses it, as it is not currently distributed with the operating system.

  Like the ToolHelp32 functions, the PSAPI.DLL also contains a variety of useful functions. However, this
  article only discusses those functions that are relevant to enumerating processes:

      EnumProcesses(), EnumProcessModules(), GetModuleFileNameEx(), GetModuleBaseName()

  EnumProcesses() is the first step in creating a list of processes in the system. Following is its
  declaration:

      BOOL EnumProcesses( DWORD *lpidProcess, DWORD cb, DWORD *cbNeeded );

  EnumProcesses() takes a pointer to a DWORD array (lpidProcess), the size of the array (cb), and a pointer
  to a DWORD to return the length of the data returned(cbNeeded). The DWORD array is populated with an
  array of process ID's for the processes in the system. The pointer to the DWORD parameter (cbNeeded)
  returns the size of the array that is used. The following calculation tells you how many process IDs were
  returned: nReturned = cbNeeded / sizeof(DWORD). One important note should be made. Although the
  documentation names the returned DWORD "cbNeeded", there is actually no way to find out how big the
  passed in array must be. EnumProcesses() will never return a value in cbNeeded that is larger than the
  size of array value that you passed in the cb parameter. As a result the only way to assure success with
  the EnumProcesses() function is to allocate a DWORD array, if cbNeeded == cb upon return, allocate a
  larger array and try again until cbNeeded is smaller than cb.

  Now you have an array with each process ID in the system. If your goal is to get the name of the process,
  then you must first get a handle. To get a handle from a process ID, use OpenProcess().

  Once you have a handle you will need to get the "first" module of the process. To get the first module of
  a process call the EnumProcessModules() API with the following parameters:

      EnumProcessModules( hProcess, &hModule, sizeof(hModule), &cbReturned );

  This will put the handle of the first module of the process in the hModule variable. Remember that a
  process doesn't really have a name, but that the first module in the process is going to be the executable
  of the process. Now you can use the hModule with the GetModuleFileNameEx(), GetModuleBaseName() to
  get the full path name, or the simple module name for the process executable. Both functions take the
  handle to the process, handle to the module, and a buffer pointer in which to return the name, followed
  by the size of the buffer.

  By repeating this for each process ID returned with the EnumProcesses(),you create a list of processes
  under Windows NT.

  16-Bit Processes:

  In Windows 95 16-bit applications are equal citizens as far as ToolHelp32 is concerned. 16-Bit
  applications have process IDs etc., just like Win32 applications. However, this is not the case under
  Windows NT.

  16-Bit applications running under Windows NT run in what is called a Virtual Dos Machine (VDM).
  EnumProcesses will not recognize any 16-bit applications in the system, however it will return the 32-bit
  NTVDM processes under which the 16-bit EXE's are running. To enumerate 16-bit applications under
  Windows NT you must use a function called VDMEnumTaskWOWEx(). You must include the VDMDBG.H in
  your source module, and the VDMDBG.LIB file should be linked with your project. These two files are
  shipped with the Platform SDK.

  The declaration of this function is as follows:

     INT WINAPI VDMEnumTaskWOWEx( DWORD dwProcessId, TASKENUMPROCEX fp,
                                  LPARAM lparam );

  where dwProcessId is the id of the NTVDM process whose 16-bit tasks you want to enumerate. The fp
  parameter is a pointer to a callback "enum" function. And the lparam parameter is a user-defined lparam
  to be passed to your enum function.

  Your "enum" function should be defined as follows:

      BOOL WINAPI Enum16( DWORD dwThreadId, WORD hMod16, WORD hTask16, PSZ
                         pszModName, PSZ pszFileName, LPARAM lpUserDefined );

  This function will be called once per 16-bit task running under the NTVDM process passed into
  VDMEnumTaskWOWEx(). You should return FALSE if you wish to continue enumerating and TRUE if you
  wish to end enumeration. NOTE: This is the opposite of EnumWindows().

  Sample Code

  The following sample code encapsulates the PSAPI.DLL and ToolHelp32 functions into one function called
  "EnumProcs()". This function works similar to EnumWindows() in that it takes a pointer to a function and
  calls it repeatedly, once for each process in the system. Following is the declaration for the function:

      BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam );

  If you use this function, the callback function should be declared as follows:

      BOOL CALLBACK Proc( DWORD dw, WORD w16, LPCSTR lpstr, LPARAM lParam );

  The dw parameter will contain the ID, the w16 is the 16-bit task number or 0 if 32-bit process (always
  zero under Windows 95), the lpstr parameter will point to the filename, and the lParam is the
  user-defined lParam passed into EnumProcs().

  The EnumProcs() function uses the ToolHelp32 and PSAPI.DLL functions via explicit linking, rather than
  the more common implicit linking. This technique is used so that the code including the EnumProcs()
  function will be binary compatible across both Windows NT and Windows 95. (For example, implicit linking
  of a ToolHelp32 function would cause an EXE to fail to load and run under Windows NT.)

     /*********************
     EnumProc.h
     *********************/
     #include <windows.h>

     typedef BOOL (CALLBACK *PROCENUMPROC)( DWORD, WORD, LPSTR,
        LPARAM ) ;

     BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam ) ;

     /*********************
     EnumProc.c (or .cpp)
     *********************/
     #include "EnumProc.h"
     #include <tlhelp32.h>
     #include <vdmdbg.h>

     typedef struct
     {
        DWORD          dwPID ;
        PROCENUMPROC   lpProc ;
        DWORD          lParam ;
        BOOL           bEnd ;
     } EnumInfoStruct ;

     BOOL WINAPI Enum16( DWORD dwThreadId, WORD hMod16, WORD hTask16,
        PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined ) ;

     // The EnumProcs function takes a pointer to a callback function
     // that will be called once per process in the system providing
     // process EXE filename and process ID.
     // Callback function definition:
     // BOOL CALLBACK Proc( DWORD dw, LPCSTR lpstr, LPARAM lParam ) ;
     //
     // lpProc -- Address of callback routine.
     //
     // lParam -- A user-defined LPARAM value to be passed to
     //           the callback routine.
     BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam )
     {
        OSVERSIONINFO  osver ;
        HINSTANCE      hInstLib ;
        HINSTANCE      hInstLib2 ;
        HANDLE         hSnapShot ;
        PROCESSENTRY32 procentry ;
        BOOL           bFlag ;
        LPDWORD        lpdwPIDs ;
        DWORD          dwSize, dwSize2, dwIndex ;
        HMODULE        hMod ;
        HANDLE         hProcess ;
        char           szFileName[ MAX_PATH ] ;
        EnumInfoStruct sInfo ;

        // ToolHelp Function Pointers.
        HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ;
        BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ;
        BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ;

        // PSAPI Function Pointers.
        BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * );
        BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *,
           DWORD, LPDWORD );
        DWORD (WINAPI *lpfGetModuleFileNameEx)( HANDLE, HMODULE,
           LPTSTR, DWORD );

        // VDMDBG Function Pointers.
        INT (WINAPI *lpfVDMEnumTaskWOWEx)( DWORD,
           TASKENUMPROCEX  fp, LPARAM );


        // Check to see if were running under Windows95 or
        // Windows NT.
        osver.dwOSVersionInfoSize = sizeof( osver ) ;
        if( !GetVersionEx( &osver ) )
        {
           return FALSE ;
        }

        // If Windows NT:
        if( osver.dwPlatformId == VER_PLATFORM_WIN32_NT )
        {

           // Load library and get the procedures explicitly. We do
           // this so that we don't have to worry about modules using
           // this code failing to load under Windows 95, because
           // it can't resolve references to the PSAPI.DLL.
           hInstLib = LoadLibraryA( "PSAPI.DLL" ) ;
           if( hInstLib == NULL )
              return FALSE ;

           hInstLib2 = LoadLibraryA( "VDMDBG.DLL" ) ;
           if( hInstLib2 == NULL )
              return FALSE ;

           // Get procedure addresses.
           lpfEnumProcesses = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))
              GetProcAddress( hInstLib, "EnumProcesses" ) ;
           lpfEnumProcessModules = (BOOL(WINAPI *)(HANDLE, HMODULE *,
              DWORD, LPDWORD)) GetProcAddress( hInstLib,
              "EnumProcessModules" ) ;
           lpfGetModuleFileNameEx =(DWORD (WINAPI *)(HANDLE, HMODULE,
              LPTSTR, DWORD )) GetProcAddress( hInstLib,
              "GetModuleFileNameExA" ) ;
           lpfVDMEnumTaskWOWEx =(INT(WINAPI *)( DWORD, TASKENUMPROCEX,
              LPARAM))GetProcAddress( hInstLib2, "VDMEnumTaskWOWEx" );
           if( lpfEnumProcesses == NULL ||
              lpfEnumProcessModules == NULL ||
              lpfGetModuleFileNameEx == NULL ||
              lpfVDMEnumTaskWOWEx == NULL)
              {
                 FreeLibrary( hInstLib ) ;
                 FreeLibrary( hInstLib2 ) ;
                 return FALSE ;
              }

           // Call the PSAPI function EnumProcesses to get all of the
           // ProcID's currently in the system.
           // NOTE: In the documentation, the third parameter of
           // EnumProcesses is named cbNeeded, which implies that you
           // can call the function once to find out how much space to
           // allocate for a buffer and again to fill the buffer.
           // This is not the case. The cbNeeded parameter returns
           // the number of PIDs returned, so if your buffer size is
           // zero cbNeeded returns zero.
           // NOTE: The "HeapAlloc" loop here ensures that we
           // actually allocate a buffer large enough for all the
           // PIDs in the system.
           dwSize2 = 256 * sizeof( DWORD ) ;
           lpdwPIDs = NULL ;
           do
           {
              if( lpdwPIDs )
              {
                 HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
                 dwSize2 *= 2 ;
              }
              lpdwPIDs = HeapAlloc( GetProcessHeap(), 0, dwSize2 );
              if( lpdwPIDs == NULL )
              {
                 FreeLibrary( hInstLib ) ;
                 FreeLibrary( hInstLib2 ) ;
                 return FALSE ;
              }
              if( !lpfEnumProcesses( lpdwPIDs, dwSize2, &dwSize ) )
              {
                 HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
                 FreeLibrary( hInstLib ) ;
                 FreeLibrary( hInstLib2 ) ;
                 return FALSE ;
              }
           }while( dwSize == dwSize2 ) ;

           // How many ProcID's did we get?
           dwSize /= sizeof( DWORD ) ;

           // Loop through each ProcID.
           for( dwIndex = 0 ; dwIndex < dwSize ; dwIndex++ )
           {
              szFileName[0] = 0 ;
              // Open the process (if we can... security does not
              // permit every process in the system).
              hProcess = OpenProcess(
                 PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
                 FALSE, lpdwPIDs[ dwIndex ] ) ;
              if( hProcess != NULL )
              {
                 // Here we call EnumProcessModules to get only the
                 // first module in the process this is important,
                 // because this will be the .EXE module for which we
                 // will retrieve the full path name in a second.
                 if( lpfEnumProcessModules( hProcess, &hMod,
                    sizeof( hMod ), &dwSize2 ) )
                 {
                    // Get Full pathname:
                    if( !lpfGetModuleFileNameEx( hProcess, hMod,
                       szFileName, sizeof( szFileName ) ) )
                    {
                       szFileName[0] = 0 ;
                      }
                 }
                 CloseHandle( hProcess ) ;
              }
              // Regardless of OpenProcess success or failure, we
              // still call the enum func with the ProcID.
              if(!lpProc( lpdwPIDs[dwIndex], 0, szFileName, lParam))
                 break ;

              // Did we just bump into an NTVDM?
              if( _stricmp( szFileName+(strlen(szFileName)-9),
                 "NTVDM.EXE")==0)
              {
                 // Fill in some info for the 16-bit enum proc.
                 sInfo.dwPID = lpdwPIDs[dwIndex] ;
                 sInfo.lpProc = lpProc ;
                 sInfo.lParam = lParam ;
                 sInfo.bEnd = FALSE ;
                 // Enum the 16-bit stuff.
                 lpfVDMEnumTaskWOWEx( lpdwPIDs[dwIndex],
                    (TASKENUMPROCEX) Enum16,
                    (LPARAM) &sInfo);

                 // Did our main enum func say quit?
                 if(sInfo.bEnd)
                    break ;
              }
           }

           HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
           FreeLibrary( hInstLib2 ) ;

        // If Windows 95:
        }else if( osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
        {


           hInstLib = LoadLibraryA( "Kernel32.DLL" ) ;
           if( hInstLib == NULL )
              return FALSE ;

           // Get procedure addresses.
           // We are linking to these functions of Kernel32
           // explicitly, because otherwise a module using
           // this code would fail to load under Windows NT,
           // which does not have the Toolhelp32
           // functions in the Kernel 32.
           lpfCreateToolhelp32Snapshot=
              (HANDLE(WINAPI *)(DWORD,DWORD))
              GetProcAddress( hInstLib,
              "CreateToolhelp32Snapshot" ) ;
           lpfProcess32First=
              (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
              GetProcAddress( hInstLib, "Process32First" ) ;
           lpfProcess32Next=
              (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
              GetProcAddress( hInstLib, "Process32Next" ) ;
           if( lpfProcess32Next == NULL ||
              lpfProcess32First == NULL ||
              lpfCreateToolhelp32Snapshot == NULL )
           {
              FreeLibrary( hInstLib ) ;
              return FALSE ;
           }

           // Get a handle to a Toolhelp snapshot of the systems
           // processes.
           hSnapShot = lpfCreateToolhelp32Snapshot(
              TH32CS_SNAPPROCESS, 0 ) ;
           if( hSnapShot == INVALID_HANDLE_VALUE )
           {
              FreeLibrary( hInstLib ) ;
              return FALSE ;
           }

           // Get the first process' information.
           procentry.dwSize = sizeof(PROCESSENTRY32) ;
           bFlag = lpfProcess32First( hSnapShot, &procentry ) ;

           // While there are processes, keep looping.
           while( bFlag )
           {
              // Call the enum func with the filename and ProcID.
              if(lpProc( procentry.th32ProcessID, 0,
                 procentry.szExeFile, lParam ))
              {
                 procentry.dwSize = sizeof(PROCESSENTRY32) ;
                 bFlag = lpfProcess32Next( hSnapShot, &procentry );
              }else
                 bFlag = FALSE ;
           }


        }else
           return FALSE ;

        // Free the library.
        FreeLibrary( hInstLib ) ;

        return TRUE ;
     }

     BOOL WINAPI Enum16( DWORD dwThreadId, WORD hMod16, WORD hTask16,
        PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined )
     {
        BOOL bRet ;

        EnumInfoStruct *psInfo = (EnumInfoStruct *)lpUserDefined ;

        bRet = psInfo->lpProc( psInfo->dwPID, hTask16, pszFileName,
           psInfo->lParam ) ;

        if(!bRet)
        {
           psInfo->bEnd = TRUE ;
        }

        return !bRet;
     }


  REFERENCES

  "Microsoft Systems Journal," August 1996 Number 8, "Under the Hood," Matt Pietrek

  "Microsoft Systems Journal," November 1996 Number 11, "Under the Hood," Matt Pietrek

  Additional query words: kbDSupport kbdss kbKernBase kbAPI kbDebug kbThread processes list listof find
  finding program running

  Keywords          :
  Version           : winnt:4.0
  Platform          : winnt
  Issue type        : kbhowto
*******************************************

let me know if you have any qyestions.
0

Featured Post

Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

591 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question