Solved

Kill process like Task Manager do

Posted on 2004-03-25
11
3,199 Views
Last Modified: 2013-12-03
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
0
Comment
Question by:MainMa
  • 4
  • 3
  • 2
  • +1
11 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 10680024
0
 
LVL 1

Expert Comment

by:GJanusz
ID: 10683203
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
 
LVL 86

Expert Comment

by:jkr
ID: 10688733
The above method covers 'TerminateProcess()' also.
0
 

Author Comment

by:MainMa
ID: 10689522
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
 
LVL 86

Expert Comment

by:jkr
ID: 10689602
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
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 1

Expert Comment

by:GJanusz
ID: 10690096
@ 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
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 50 total points
ID: 10692339
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
 
LVL 86

Expert Comment

by:jkr
ID: 10692355
>>Try this:

Funny, looks like the code of both aforementioned articles combined...
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 10692408
>> 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
 

Author Comment

by:MainMa
ID: 10699507
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
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 10699611
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

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

708 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

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now