VisualStudio でプロセスIDからプロセス名を取得

環境

Visual Studio 2015

参考サイト

Geekなぺーじ:プロセス名一覧を取得する

使用する Win API

  • 呼び出し側プロセスのプロセス識別子を取得します(GetCurrentProcessId)
  • 既存のプロセスオブジェクトのハンドルを開きます(OpenProcess)
  • 指定されたプロセス内の各モジュールのハンドルを取得します(EnumProcessModules)
  • 開いているオブジェクトハンドルを閉じます(CloseHandle)
  • 指定されたモジュールのベース名を取得します(GetModuleBaseName)

Sample

#include "stdafx.h"

#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <psapi.h>

static const int PROCESS_SUCCESS = 0;
static const int PROCESS_OPEN_ERROR = -1;
static const int PROCESS_ENUM_MODULES_ERROR = -2;
static const int PROCESS_GET_BASE_NAME_ERROR = -3;
static const int PROCESS_CLOSE_HANDLE_EXCEPTION = -4;


// processName には _MAX_PATH のバッファを確保しておくこと
short GetProcessName(DWORD processId, TCHAR* processNameBuff )
{
    HANDLE hProcess = NULL;
    short result = PROCESS_SUCCESS;
    try
    {
        // プロセスをオープン
        hProcess = OpenProcess(
            PROCESS_ALL_ACCESS, FALSE, processId);
        if (NULL == hProcess)       // 関数が失敗すると、NULL が返る
        {
            throw PROCESS_OPEN_ERROR;
        }

        // モジュールハンドルを取得
        HMODULE hMod;
        DWORD cbNeeded;
        BOOL ret = EnumProcessModules(
            hProcess, &hMod, sizeof(hMod), &cbNeeded);
        if (ret == 0)               // 関数が失敗すると、0 が返る
        {
            throw PROCESS_ENUM_MODULES_ERROR;
        }

        // モジュールベースネームを取得
        DWORD procNameLength = GetModuleBaseName(
            hProcess, hMod, processNameBuff, _MAX_PATH);
        if (procNameLength == 0)    // 関数が失敗すると、0 が返る
        {
            throw PROCESS_GET_BASE_NAME_ERROR;
        }

    }
    catch(int num)
    {
        result = num;
        printf("Error(%d)(%d)\n", result, GetLastError());
    }

    try
    {
        // プロセスハンドルをクローズ
        if (hProcess)
        {
            CloseHandle(hProcess);
        }
    }
    catch (...)
    {
        result = PROCESS_CLOSE_HANDLE_EXCEPTION;
        printf("Exception(%d)\n", GetLastError());
    }

    return result;
}


int main()
{
    TCHAR procName[MAX_PATH] = { 0x00 };
    DWORD processId = GetCurrentProcessId();

    if (PROCESS_SUCCESS != GetProcessName(processId, procName))
    {
        printf("GetProcessName Error\n");
    }

    // プロセス名とPIDを表示
    _tprintf(TEXT("%s  (PID: %u)\n"), procName, processId);

    return 0;
}

logを見やすくするエイリアス設定

gitのlogを見やすくするためgraphのエイリアス設定をする

~/.gitconfigに以下を追記。

[alias]
  graph = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
  grapha = log --graph --all --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative

参考サイト

美しき git log --graph のエイリアス - Hack Your Design!
Gitのちょっと便利な使い方 (ゆめ技:ゆめみスタッフブログ)

gtest 実行時のオプション

参考サイト

上級ガイド — Google Test ドキュメント日本語訳

特に便利なオプション

--gtest_output

テスト実行時に引数 --gtest_output=xml:<結果ファイル名>.xml を付けることでxmlで結果を出力できる
Jenkinsに喰わせると見やすい

例:結果を test_result.xml として出力

Sample.exe --gtest_output=xml:test_result.xml
  • <結果ファイル名> を指定しない場合、 'detail.xml' というファイル名で出力される

--gtest_filter

実行するテストをフィルタリングすることで指定できる。

指定例 説明
--gtest_filter=TestClass.* テストクラス名がTestClassのテストのみ実行する
--gtest_filter=*.TestCase1 テストケース名がTestCase1のテストのみ実行する
--gtest_filter=-*.TestCase1 テストケース名がTestCase1のテスト以外のテストのみ実行する
--gtest_filter=TestClass.*-TestClass.TestCase1 テストクラス名がTestClassでテストケースがTestCase1を除いたテストのみ実行する

--gtest_repeat

テストを繰り返す回数を指定する。-1指定で無限に繰り返す。

--gtest_break_on_failure

テストでFailしたら後続のテストを実行しない(中断)。

--gtest_print_time

テスト実行に要した時間を出力。(テストケース単位)

--gtest_list_tests

テストの一覧を表示する。(テスト実行はしない)

Visual Studio で gtest を使う

参考サイト

入門ガイド — Google Test ドキュメント日本語訳
上級ガイド — Google Test ドキュメント日本語訳
ビルドのコマンドとプロパティのマクロ

環境

手順

プロジェクト作成

ファイル -> 新規作成 -> プロジェクト -> 名前欄に任意の名前を入力(ここでは"Sample"とした場合の説明) -> Win32 コンソールアプリケーション -> OK -> 次へ -> 完了

gtestの準備

  • 下記サイトから gtest-1.7.0.zip をダウンロード
    Downloads - googletest - Google C++ Testing Framework - Google Project Hosting

  • 解凍したフォルダの下記ソリューションファイルをダブルクリックし、Visual Studio を起動

      gtest-1.7.0\msvc\gtest-md.sln
    
  • ソリューションのビルド(Release/Debugいずれも) を行い、下記のファイルが生成されることを確認

      gtest-1.7.0\msvc\gtest\Debug\gtestd.lib
      gtest-1.7.0\msvc\gtest\Debug\gtest_maind.lib
    
      gtest-1.7.0\msvc\gtest\Release\gtest.lib
      gtest-1.7.0\msvc\gtest\Release\gtest_main.lib
    
  • 下記の通りフォルダ構成を整える

      Sample
      │  Sample.sdf
      │  Sample.sln
      │  README.md
      │
      │
      └─Sample
         │  Sample.cpp
         │  Sample.vcxproj
         │  Sample.vcxproj.filters
         │  ReadMe.txt
         │  stdafx.cpp
         │  stdafx.h
         │  targetver.h
         │
         ├─include     // gtest-1.7.0\include をコピー
         │
         └─lib         // gtest-1.7.0\msvc\gtest 以下をコピー
             ├─Debug
             └─Release
    

INCLUDEディレクトリの追加

ソリューション右クリック -> プロパティ -> 構成プロパティ -> C/C++ -> [追加のインクルードディレクトリ] -> gtestのincludeディレクトリを追加
※$(ProjectDir)を使用して追加した方がよい

例:$(ProjectDir)include

libファイルのリンク設定

ソリューション右クリック -> プロパティ -> 構成プロパティ -> リンカー -> [追加のライブラリディレクトリ] -> gtestのlibのディレクトリを追加 $(Configuration)を利用して追加した方がよい

例:$(ProjectDir)lib\$(Configuration)

ソリューション右クリック -> プロパティ -> 構成プロパティ -> リンカー -> 入力 -> [追加の依存ファイル] ->

構成を[Release] に設定し、下記を追加
gtest.lib
gtest_main.lib

構成を[Debug] に設定し、下記を追加
gtestd.lib
gtest_maind.lib

ランタイムライブラリのリンク方法の指定を変更

ソリューション右クリック -> プロパティ -> 構成プロパティ -> C/C++ -> コード生成 -> [ランタイムライブラリ] ->

構成を[Release] に設定し、[マルチスレッド (/MT)] を設定

構成を[Debug] に設定し、[マルチスレッド デバッグ (/MTd)] を設定

テスト実行

テスト実行時に引数 --gtest_output=xml:<結果ファイル名>.xml を付けることでxmlで結果を出力できる

例:結果を test_result.xml として出力

Sample.exe --gtest_output=xml:test_result.xml