Kill process like Task Manager do

I work under Windows XP. How can I kill a process in Visual C++ program, by just specifing it's name?
For example, I have Media Player running. Task Manager shows that the program name is wmplayer.exe. Now, can I end the process as I do it with Task Manager?

Thanks,
MainMa
MainMaAsked:
Who is Participating?
 
itsmeandnobodyelseCommented:
Try this:

// enumproc.h

#ifndef ENUMPROC_H
#define ENUMPROC_H    
                                                                                                     
#include <vdmdbg.h>                                                                                  

typedef BOOL (CALLBACK *PROCENUMPROC)( DWORD, WORD, LPSTR, LPARAM ) ;                                                                                            
                                                                                                         
BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, TASKENUMPROCEX lpTask, LPARAM lParam ) ;

#endif  // ENUMPROC_H

//------------------------------------------------------------------------------------------------------------------------

// enumproc.cpp

#include <windows.h>                                                                                      

#include "enumproc.h"                                                                                
#include <tlhelp32.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, TASKENUMPROCEX lpTask, 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 = (DWORD*)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) lpTask,                                                              
               (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;                                                                                    
}                                                                                                    

//-----------------------------------------------------------------------------------------------------------------------------

// killproc.h


#ifndef KILLPROC_H
#define KILLPROC_H

class EnumerateProcesses
{
private:
    int     m_count;
    char*   m_pszProcToKill;

public:
    EnumerateProcesses(char* pszProcToKill = NULL)
        : m_count(0), m_pszProcToKill(pszProcToKill) {}
    ~EnumerateProcesses() {}

public:
    BOOL    run();
    int     getIncrementedCount()   { return ++m_count; }
    char*   getProcToKill()         { return m_pszProcToKill; }

public:
    static
    BOOL CALLBACK enumProcessCallback( DWORD dw32Id, WORD w16Id, LPSTR pszModule, LPARAM lany);
    static
    BOOL WINAPI   enumVDMTaskCallback( DWORD dwThreadId, WORD hMod16, WORD hTask16,                                    
                                       LPSTR pszModName, LPSTR pszFileName, LPARAM lany ) ;                                        
                                                                                                     
};
#endif // KILLPROC_H

//---------------------------------------------------------------------------------------------------------

// killproc.cpp

// killproc.cpp : Defines the entry point for the console application.
//

#include <windows.h>
#include <iostream>

#include "enumproc.h"
#include "killproc.h"

using namespace std;

int main(int nArgs, char* szArgs[])
{
      int nRetCode = 0;

    if (nArgs > 2)
    {
            cout << "Fatal Error: Wrong number of arguments" << endl;
            nRetCode = 1;

    }
      else
      {
        char* pszProcToKill = NULL;
        if (nArgs > 1)
        {
            pszProcToKill = szArgs[1];
        }

        EnumerateProcesses  enumProc(pszProcToKill);


        BOOL ok = enumProc.run();

        nRetCode = GetLastError();

      }

      return nRetCode;
}

BOOL EnumerateProcesses::run()
{
    m_count = 0;
    return EnumProcs( EnumerateProcesses::enumProcessCallback, EnumerateProcesses::enumVDMTaskCallback, (LPARAM)this);
}

BOOL EnumerateProcesses::enumProcessCallback( DWORD dw32Id, WORD w16Id, LPSTR pszModule, LPARAM pThis)
{
    EnumerateProcesses* pEP = (EnumerateProcesses*) pThis;

    char*   pszProcToKill   = pEP->getProcToKill();

    BOOL    bKill           = FALSE;

    if (pszProcToKill != NULL)
    {
        string strModule = pszModule;
        string strProc   = pszProcToKill;

        int i = 0;
        for (i = 0; i < strModule.length(); i++)
            toupper(strModule[i]);
        int  nSepPos = strModule.find_first_of("\\/");
        int  nDotPos = strModule.find(".EXE");
        for (i = 0; i < strProc.length(); i++)
            toupper(strProc[i]);


        if (nSepPos >= 0)
        {
            strProc.insert(0, strModule[nSepPos]);
            if (strProc.find('.') == string::npos && nDotPos == strModule.length()-4)
            {
                nSepPos = strModule.rfind(strModule.at(nSepPos));
                if (nSepPos < nDotPos)
                {
                    strProc += ".EXE";
                }
            }
        }
       
        bKill = strModule.find(strProc) != string::npos;
           
    }



    if (bKill)
    {
        cout << pEP->getIncrementedCount() << "\t" << pszModule << endl;
        HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, dw32Id);
        if (hProc == NULL)
        {
            cout << "Could not open process " << pszProcToKill << endl;
        }
        else
        {
            if (TerminateProcess(hProc, 1) == 0)
            {
                cout << "Could not terminate process " << pszProcToKill << endl;
            }
            else
            {
                cout << "Successfully terminated process " << pszProcToKill << endl ;
            }
        }


    }

    return TRUE;
}
       
BOOL EnumerateProcesses::enumVDMTaskCallback( DWORD dwThreadId, WORD hMod16, WORD hTask16,                                    
                                              LPSTR pszModName, LPSTR pszFileName, LPARAM pThis )
{
    EnumerateProcesses* pEP = (EnumerateProcesses*) pThis;
    return TRUE;

}

//-------------------------------------------------------------------------------------------------

If you call the project killproc you may run it from the commandline like this

    killproc calc

Then it terminates calc.exe. If there are more than one instances it terminates all. However, it couldn't terminate services and other protected system processes as TaskMgr couldn't either;

Regards, Alex
0
 
jkrCommented:
0
 
GJanuszCommented:
The above-mentioned method is how to do it when the program is still in relatively good condition (i.e., still processing windows messages).  You rely on it correctly processing the WM_CLOSE message.  If it is unable to do so , such as when it is in an infinite loop, or stuck waiting for a resource, then:

Get the process' handle (see 2nd above-mentioned link), and then use
::TerminateProcess().
0
Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

 
jkrCommented:
The above method covers 'TerminateProcess()' also.
0
 
MainMaAuthor Commented:
Is it possible to have a function like GetProcessImageFileName, but which, instead of returning the filename of an executable from a handle will return a handle from a filename? I can only use an executable filename, because, for some processes, I haven't got windows IDs or handles.
0
 
jkrCommented:
You need to enumerate all running processes and check whether the filename matches - see e.g. http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q175/0/30.ASP&NoWebContent=1 ("HOWTO: Enumerate Applications Using Win32 APIs") as mentioned earlier.
0
 
GJanuszCommented:
@ Author

No, you can't.  Logically, this makes sense.  Which handle would be returned if two instances of an application were running (i.e., have the same name).  You see this with svchost.exe and iexplore.exe, but could see it with one of your own applications, as well.
0
 
jkrCommented:
>>Try this:

Funny, looks like the code of both aforementioned articles combined...
0
 
itsmeandnobodyelseCommented:
>> Funny, looks like the code of both aforementioned articles combined...

I don't know anymore where i got this code. It has been some years ago and most likely it has been from of any of these sites above.

But i adopted it - i added STL, removed any MFC parts and used my own 'notation' ;-)  - and it is tested now.

Regards, Alex

0
 
MainMaAuthor Commented:
Sorry, I were absent, so I couldn't answer. The code, given by "itsmeandnobodyelse" works, but only for some programs. I haven't much time to see what doesn't work, but I suppose I can ask for more information after accepting your answer.

MainMa
0
 
itsmeandnobodyelseCommented:
Because of this statement:

  HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, dw32Id);

you can only kill processes that allow process termination.

However, when i replaced MFC CString by std::string i made a mistake that makes the flag bKill always true. After calling killproc i got a black desktop cause all programs had been teminated. I had to call TaskManager using CTRL-ALT-DEL and restart explorer to get my desktop back ;-)

Regards, Alex

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.