web-dev-qa-db-ja.com

C ++(Win32)でプロセスを効果的に強制終了する方法

現在、非常に軽量なプログラムを作成しているため、プログラムのサイズが大幅に増加する.NETフレームワークにバインドされていないため、C++を使用する必要があります。

プロセスを終了できるようにする必要があり、そのためにはプロセスハンドルを取得する必要があります。不幸にも、その方法をまだ理解していません。

追伸プロセスを強制終了するには、TerminateProcessを使用する必要があることを知っています。

16
Kristina Brooks

OpenProcess()に必要なPIDは、通常、簡単に入手できません。取得したのがプロセス名だけの場合は、マシンで実行中のプロセスを繰り返す必要があります。 CreateToolhelp32Snapshot、Process32Firstの順に実行し、Process32Nextでループします。 PROCESSENTRY32.szExeFileはプロセス名(パスではありません!)を提供し、th32ProcessIDはPIDを提供します。

次の考慮事項は、プロセスが複数回表示される可能性があることです。また、非常に異なるプログラムで同じプロセス名が使用される可能性があります。 「セットアップ」のように。それらすべてを単に殺したくない場合は、それらからいくつかのランタイム情報を取得しようとする必要があります。ウィンドウのキャプションバーのテキスト。 GetProcessImageFileName()は、.exeへのパスを提供します。ネイティブカーネル形式を使用します。ディスクドライブのデバイス名をドライブ文字にマップするには、QueryDosDeviceが必要です。

次の考慮事項は、OpenProcess()で要求する権利です。あなたが得る可能性は低いですPROCESS_ALL_ACCESS、 あなたに必要なのは PROCESS_TERMINATE。それも特権ですが。プログラムの実行に使用するアカウントがその権利を取得できることを確認してください。

16
Hans Passant

既知の名前のプロセスを強制終了するためにそのすべての苦痛を経験するのではなく、単に「システム」を呼び出して、コマンドラインに強制終了するよう依頼しないのはなぜですか?

例えば、

int retval = ::_tsystem( _T("taskkill /F /T /IM MyProcess.exe") );
14
James Hugard
HANDLE Explorer;
Explorer = OpenProcess(PROCESS_ALL_ACCESS,false,2120);
TerminateProcess(Explorer,1);

うまくいった

11
Kristina Brooks

TerminateProcess に渡すハンドルを取得するには、 EnumProcesses などの他の関数と組み合わせて OpenProcess を使用します。

5
Jon Benedicto

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();
                }
            }
        }
    }
}
4
Developer

CreateProcess および OpenProcess プロセスハンドルを返します。

ここにいくつかの サンプルコード を使用して、システムにすべてのプロセスを一覧表示するように要求し、必要なプロセスのリストを検索します。

1
Jason Orendorff

窓のみ

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

「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);
                }
            }
        }
    }
}
0
laishiekai