如何有效地杀死C ++(Win32)中的进程?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何有效地杀死C ++(Win32)中的进程?相关的知识,希望对你有一定的参考价值。

我目前正在编写一个非常轻量级的程序,所以我必须使用C ++,因为它不受.NET框架的约束,这大大增加了程序的大小。

我需要能够终止进程并且这样做我需要获得进程句柄。不幸的是,我还没有想到如何做到这一点。

附:我知道要杀死一个进程你必须使用TerminateProcess。

答案

OpenProcess()所需的PID通常不容易掌握。如果你得到的只是一个进程名称,那么你需要在机器上迭代正在运行的进程。使用CreateToolhelp32Snapshot执行此操作,然后执行Process32First并使用Process32Next循环。 PROCESSENTRY32.szExeFile为您提供进程名称(不是路径!),th32ProcessID为您提供PID。

下一个考虑因素是该过程可能不止一次出现。并且有可能将相同的进程名称用于非常不同的程序。像“设置”。如果你不想只杀死它们,你需要尝试从它们获取一些运行时信息。也许是窗口标题栏文本。 GetProcessImageFileName()可以为您提供.exe的路径。它使用本机内核格式,您需要QueryDosDevice将磁盘驱动器设备名称映射到驱动器号。

下一个考虑因素是您在OpenProcess()中要求的权限。你不太可能得到PROCESS_ALL_ACCESS,你需要的只是PROCESS_TERMINATE。虽然这也是特权。确保用于运行程序的帐户可以获得该权限。

另一答案

为什么不简单地调用“系统”并要求命令行杀死它,而不是通过所有的痛苦来杀死具有已知名称的进程?

例如,

int retval = ::_tsystem( _T("taskkill /F /T /IM MyProcess.exe") );
另一答案
HANDLE explorer;
explorer = OpenProcess(PROCESS_ALL_ACCESS,false,2120);
TerminateProcess(explorer,1);

那很有效

另一答案

要获得传递给TerminateProcess的句柄,请将OpenProcessEnumProcesses等其他函数结合使用。

另一答案

以下是Visual Studio 2010 C ++项目如何通过EXE文件名终止进程的完整示例。

为了检查它,只需运行Internet Explorer,然后执行以下代码。

#include <iostream>
#include <string>
#include<tchar.h>
#include <process.h>
#include <windows.h>
#include <tlhelp32.h>

using namespace std;

//  Forward declarations:
BOOL GetProcessList();
BOOL TerminateMyProcess(DWORD dwProcessId, UINT uExitCode);

int main( void )
{
  GetProcessList( );
  return 0;
}

BOOL GetProcessList( )
{
  HANDLE hProcessSnap;
  HANDLE hProcess;
  PROCESSENTRY32 pe32;
  DWORD dwPriorityClass;

  // Take a snapshot of all processes in the system.
  hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
  if( hProcessSnap == INVALID_HANDLE_VALUE )
  {   
    return( FALSE );
  }

  // Set the size of the structure before using it.
  pe32.dwSize = sizeof( PROCESSENTRY32 );

  // Retrieve information about the first process,
  // and exit if unsuccessful
  if( !Process32First( hProcessSnap, &pe32 ) )
  {   
    CloseHandle( hProcessSnap );  // clean the snapshot object
    return( FALSE );
  }

  // Now walk the snapshot of processes 
  do
  {  
    string str(pe32.szExeFile);

    if(str == "iexplore.exe") // put the name of your process you want to kill
    {
        TerminateMyProcess(pe32.th32ProcessID, 1);
    } 
  } while( Process32Next( hProcessSnap, &pe32 ) );

  CloseHandle( hProcessSnap );
  return( TRUE );
}

BOOL TerminateMyProcess(DWORD dwProcessId, UINT uExitCode)
{
    DWORD dwDesiredAccess = PROCESS_TERMINATE;
    BOOL  bInheritHandle  = FALSE;
    HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
    if (hProcess == NULL)
        return FALSE;

    BOOL result = TerminateProcess(hProcess, uExitCode);

    CloseHandle(hProcess);

    return result;
}

想象一下在C#中它看起来像

using System;
using System.Collections.Generic;
using System.Text;

namespace MyProcessKiller
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (System.Diagnostics.Process myProc in System.Diagnostics.Process.GetProcesses())
            {
                if (myProc.ProcessName == "iexplore")
                {
                    myProc.Kill();
                }
            }
        }
    }
}
另一答案

CreateProcessOpenProcess返回进程句柄。

这里有一些sample code通过要求系统列出所有进程然后在列表中搜索您想要的进程来查找进程。

另一答案

以下是一些工作示例代码,用于终止名为“ShouldBeDead.exe”的进程:

// you will need these headers, and you also need to link to Psapi.lib
#include <tchar.h>
#include <psapi.h>

...
// first get all the process so that we can get the process id 
DWORD processes[1024], count;
if( !EnumProcesses( processes, sizeof(processes), &count ) )
{
    return false;
}

count /= sizeof(DWORD);
for(unsigned int i = 0; i < count; i++)
{
    TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
    if(processes[i] != 0)
    {
        // remember to open with PROCESS_ALL_ACCESS, otherwise you will not be able to kill it
        HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, processes[i] );
        if(NULL != hProcess)
        {
            HMODULE hMod;
            DWORD cbNeeded;
            if(EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
            {
                GetModuleBaseName(hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR));

                // find the process and kill it
                if(strcmp(szProcessName, "ShouldBeDead.exe") == 0)
                {
                    DWORD result = WAIT_OBJECT_0;
                    while(result == WAIT_OBJECT_0)
                    {
                        // use WaitForSingleObject to make sure it's dead
                        result = WaitForSingleObject(hProcess, 100);
                        TerminateProcess(hProcess, 0);
                    }

                    CloseHandle(hProcess);
                }
            }
        }
    }
}
另一答案

只有窗户

system("taskkill /f /im servicetokill.exe")

以上是关于如何有效地杀死C ++(Win32)中的进程?的主要内容,如果未能解决你的问题,请参考以下文章

在Win32(c ++)中的另一个进程中写入文本框

如何在按钮单击时从win32 c ++中的文本框获取文本?

win32 C++上的按钮样式

用VS2012如何执行C语言编写的程序?

C++/Win32 - 如何迭代特定进程的线程列表并将起始地址解析为模块?

Perl - Win32 - 如何从另一个进程非阻塞读取文件句柄?