C++ Builder Tokyo > ProcessLogger > 指定の.exeファイルのプロセスIDをロギングする v0.1 (XE4からの移行対応)

```txt:動作環境
Windows 10 Pro (64bit) バージョン 1803 (April 2018 Update)
RAD Studio 10.2 Tokyo Update 3
```

## XE4からTokyoへの移行

- [C++ Builder XE4 > ProcessLogger > 指定の.exeファイルのプロセスIDをロギングする v0.1](https://qiita.com/7of9/items/3ac4c8768a8bb873db17#%E5%AE%9F%E8%A3%85)

XE4の実装はTokyoでビルドできないようだ。

下記の変更をする。

- 変更前: `#include <Tlhelp32.hpp>`
    - 変更後: `#include <Tlhelp32.h>`
    - 理由: THelpで`C:\\Program Files(x86)\\Embarcadero\Studio\19.0`以下を検索時、`tlhelp32.h`が見つかったため
- 変更前: `TProcessEntry32`
    - 変更後: `PROCESSENTRY32`
    - 参考: https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/ns-tlhelp32-tagprocessentry32


### 実装 v0.1

```Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
    TMemo *Memo1;
    TEdit *E_exeName;
    TButton *Button1;
    TCheckBox *CHK_log;
    TTimer *TMR_logging;
    void __fastcall FormDestroy(TObject *Sender);
    void __fastcall Button1Click(TObject *Sender);
    void __fastcall TMR_loggingTimer(TObject *Sender);
private:	// ユーザー宣言
    int __fastcall ListUpProcess_NameOf(String exename);
    void __fastcall checkProcessID(void);
    TStringList *m_logSL; // ロギング用
public:		// ユーザー宣言
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

```

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

//(2018.11.19) XE4からTokyoへの対応
//#include <Tlhelp32.hpp>
#include <Tlhelp32.h>
//
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

static const String kFilename_log = L"ProcLogger.csv"; // ログ用

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    Memo1->Lines->Clear();

    //
    m_logSL = new TStringList();

    // ログタイマー設定
    TMR_logging->Enabled = false;
    TMR_logging->Interval = 10000; // msec
    TMR_logging->Enabled = true;
}

void __fastcall TForm1::FormDestroy(TObject *Sender)
{
    delete m_logSL;
}
//---------------------------------------------------------------------------

int __fastcall TForm1::ListUpProcess_NameOf(String exename)
{
    HANDLE ListHandle;  // タスクマネージャ > プロセスリスト 用ハンドル

    //(2018.11.19) XE4からTokyoへの対応
    //TProcessEntry32 Pentry; // 個々のプロセス閲覧用
    PROCESSENTRY32 Pentry; // 個々のプロセス閲覧用

    ListHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (ListHandle == INVALID_HANDLE_VALUE) {
        return 0;
    }

    //(2018.11.19) XE4からTokyoへの対応
    //Pentry.dwSize = sizeof(TProcessEntry32);
    Pentry.dwSize = sizeof(PROCESSENTRY32);
    //
    Process32First(ListHandle, &Pentry);
    while(1) {
        String pnam = Pentry.szExeFile;
        int procId = Pentry.th32ProcessID;
        if (pnam.Pos(exename) > 0) {
            return procId;
        }

        if (Process32Next(ListHandle, &Pentry) == false) {
            break;
        }
    }
    return 0;
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    checkProcessID();
}

void __fastcall TForm1::checkProcessID(void)
{
    int procId = ListUpProcess_NameOf(E_exeName->Text);

    String msg;
    msg = Now().FormatString(L"yyyy/mm/dd,hh:nn:ss");
    msg += L",procID," + IntToStr(procId);
    Memo1->Lines->Add(msg);

    m_logSL->Add(msg);
}

//---------------------------------------------------------------------------
void __fastcall TForm1::TMR_loggingTimer(TObject *Sender)
{
    if (CHK_log->Checked) {
        checkProcessID();
        m_logSL->SaveToFile(kFilename_log);
    }
}
//---------------------------------------------------------------------------
```

### 動作例

![2018-11-19_17h35_30.png](https://qiita-image-store.s3.amazonaws.com/0/32870/a8b7e6b5-9ded-9505-9328-5c55745c99a7.png)