Mesoscopic Programming

タコさんプログラミング専門

プロセス関係の関数を作った

プロセス関係の関数を作ったので置いておきます。
マルチプロセスのプログラムをデバッグしていると、
自分以外のプロセスを殺したくなりますよね。
いちいち手作業で殺すのはめんどくさいので、
自動で殺すためのお助け関数を作りました。
これでプロセス識別子からハンドルをゲットして、
ターミネートしてやれば自動で殺せますよね。

親プロセス識別子取得関数
    //-------------------------------------------------------------------------
    /// 親プロセス識別子取得関数
    ///
    /// 親プロセス識別子取得関数です。
    ///
    /// @param[in] value プロセス識別子
    /// @return    プロセス識別子
    /// @attention なし
    ///
    DWORD GetParentProcess( DWORD value ) {
        // 実行結果を初期化する
        DWORD result = 0;

        // プロセススナップショットを作成する
        HANDLE snap = ::CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
        if ( nullptr != snap ) {
            // 最初のプロセス情報を取得する
            PROCESSENTRY32 pe;
            pe.dwSize = sizeof( PROCESSENTRY32 );
            BOOL result2 = ::Process32First( snap, &pe );

            // プロセス情報を巡回する
            while ( TRUE == result2 ) {
                // プロセス識別子を調べる
                if ( value == pe.th32ProcessID ) {
                    // 親プロセス識別子を取得する
                    result = pe.th32ParentProcessID;
                    break;
                }

                // 次のプロセス情報を取得する
                pe.dwSize = sizeof( PROCESSENTRY32 );
                result2 = ::Process32Next( snap, &pe );
            }
        }

        // 実行結果を返す
        return result;
    }
解説

自分を起動したプロセスが誰なのかを知りたいです。
他のプロセスのためのプロセスならば、
親が特定のプロセスでなければ意味がありませんから。

プロセス実行ファイルパス取得関数
    //-------------------------------------------------------------------------
    /// プロセス実行ファイルパス取得関数
    ///
    /// プロセス実行ファイルパス取得関数です。
    ///
    /// @param[in]  id     プロセス識別子
    /// @param[out] buffer 文字列バッファ
    /// @param[out] size   バッファサイズ
    /// @return     文字列ポインタ
    /// @attention  なし
    ///
    char const* GetProcessExeFilePath( DWORD id, char* buffer, size_t size ) {
        // 実行結果を初期化する
        char const* result = nullptr;

        // モジュールスナップショットを作成する
        HANDLE snap = ::CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, id );
        if ( nullptr != snap ) {
            // 最初のモジュール情報を取得する
            MODULEENTRY32 me;
            me.dwSize = sizeof( MODULEENTRY32 );
            BOOL result2 = ::Module32First( snap, &me );

            // モジュール情報を巡回する
            while ( TRUE == result2 ) {
                // プロセス識別子を調べる
                if ( id == me.th32ProcessID ) {
                    // プロセス実行ファイルパスを取得する
                    ::strcpy_s( buffer, size, me.szExePath );

                    // 文字列ポインタを設定する
                    result = buffer;
                    break;
                }

                // 次のプロセス情報を取得する
                me.dwSize = sizeof( MODULEENTRY32 );
                BOOL result2 = ::Module32Next( snap, &me );
            }
        }

        // 実行結果を返す
        return result;
    }
解説

親プロセスの識別子が分かったなら、
その実行ファイルパスから
目的とするプロセスかどうか
判断できますよね。

プロセス検索関数
    //-------------------------------------------------------------------------
    /// プロセス検索関数
    ///
    /// プロセス検索関数です。
    ///
    /// @param[in] value プロセス実行ファイルパス
    /// @return    プロセス識別子
    /// @attention なし
    ///
    //-------------------------------------------------------------------------
    // プロセス検索関数
    DWORD SearchProcess( char const* value ) {
        // 実行結果を初期化する
        DWORD result = 0;

        // プロセススナップショットを作成する
        HANDLE snap_process = ::CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
        if ( nullptr != snap_process ) {
            // 最初のプロセス情報を取得する
            PROCESSENTRY32 pe;
            pe.dwSize = sizeof( PROCESSENTRY32 );
            BOOL result2 = ::Process32First( snap_process, &pe );

            // プロセス情報を巡回する
            while ( TRUE == result2 ) {
                // モジュールスナップショットを作成する
                HANDLE snap_module = ::CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, pe.th32ProcessID );
                if ( nullptr != snap_module ) {
                    // 最初のモジュール情報を取得する
                    MODULEENTRY32 me;
                    me.dwSize = sizeof( MODULEENTRY32 );
                    BOOL result2 = ::Module32First( snap_module, &me );

                    // モジュール情報を巡回する
                    while ( TRUE == result2 ) {
                        // プロセス実行ファイルパスを調べる
                        if ( 0 == ::_strcmpi( value, me.szExePath ) ) {
                            // プロセス識別子を取得する
                            result = pe.th32ProcessID;
                            break;
                        }

                        // 次のプロセス情報を取得する
                        me.dwSize = sizeof( MODULEENTRY32 );
                        BOOL result2 = ::Module32Next( snap_module, &me );
                    }

                    // 実行結果を調べる
                    if ( 0 != result ) {
                        // ブレークする
                        break;
                    }
                }

                // 次のプロセス情報を取得する
                pe.dwSize = sizeof( PROCESSENTRY32 );
                result2 = ::Process32Next( snap_process, &pe );
            }
        }

        // 実行結果を返す
        return result;
    }
解説

いろんなプロセスを殺したいときってありますよね。
ファイル名だけだと同じ名前の他人だったりするから、
ちゃんとフルパスで探してあげてね。
あと
必要なヘッダはこんな感じです。

#include <windows.h>
#include <string.h>
#include <tlhelp32.h>

もし足りなかったらぼめんなさい。

以上です。