MetaTraderのプロセス監視をする（C#で

# 目的
MetaTrader用のプロセス監視ツールを作る。

# 画面構成

プロセス監視中なら緑(button1)で表示されます。
MetaTraderの起動は，起動ボタンで行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531802/5fb1d85a-805c-d64e-62a0-9599fb278382.png)

また，起動したいファイルのexeファイルの絶対パスを入力できるようにします。
大したことではないのですが，この絶対パスをつかって，起動ボタンでMetaTraderを起動できます・・・。

# コード解説
解説するほどのコードではないのですが・・・

button1のクリックイベントには次を割り当てます。
```C#
private void button1_Click(object sender, EventArgs e)
{
    button1.Text = "プロセス監視中";
    button1.BackColor = Color.Chartreuse;
    TimerCallback timerDelegate = new TimerCallback(kanshi);
    timer = new System.Threading.Timer(timerDelegate, null, 0, 1000);

}
```

button1を押したとき，監視用のスレッディングタイマーを動かして，１秒ごとに監視を始めます。

以下のコードで監視しています。"terminal"というプロセスがなければ，setFocus()を呼びます。

```C#
public void kanshi(object o)
    {
        int qab = 0;
        //ローカルコンピュータ上で実行されているすべてのプロセスを取得
        System.Diagnostics.Process[] ps =
            System.Diagnostics.Process.GetProcesses();
        //"machinename"という名前のコンピュータで実行されている
        //すべてのプロセスを取得するには次のようにする。
        //System.Diagnostics.Process[] ps =
        //    System.Diagnostics.Process.GetProcesses("machinename");

        //配列から1つずつ取り出す
        foreach (System.Diagnostics.Process p in ps)
        {
            try
            {
                if (p.ProcessName.Equals("terminal"))
                {
                    qab = 1;
                    //プロセス名を出力する
                    //Console.WriteLine("プロセス名: {0}", p.ProcessName);
                    //ID
                    //Console.WriteLine("ID: {0}", p.Id);
                    //メインモジュールのパス
                    //Console.WriteLine("ファイル名: {0}", p.MainModule.FileName);
                    //合計プロセッサ時間
                    //Console.WriteLine("合計プロセッサ時間: {0}", p.TotalProcessorTime);
                    //物理メモリ使用量
                    //Console.WriteLine("物理メモリ使用量: {0}", p.WorkingSet64);
                    //.NET Framework 1.1以前では次のようにする
                    //Console.WriteLine("物理メモリ使用量: {0}", p.WorkingSet);

                    Console.WriteLine();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("エラー: {0}", ex.Message);
            }
        }

        if(qab == 0)
        {
            SetFocus();
        }

    }
```

スレッディングタイマーはUIスレッドと別で動いているので，InvokeでUIスレッドをいじれるようにします。

```C#
delegate void FocusDelegate();

void SetFocus()
{
    if (InvokeRequired)
    {
        // 別スレッドから呼び出された場合
        Invoke(new FocusDelegate(SetFocus));
        return;
    }
    button1.Text = "プロセス異常終了";
    button1.BackColor = Color.OrangeRed;

    lineNotify("\nMT4が突然終了しました。\n早く確認しなさい。");
    timer.Change(Timeout.Infinite, Timeout.Infinite);
}
```


UI側をいじりつつ，lineNotifyでLINE通知もしたいと思います。

```C#
public void lineNotify(String strMsg)
{
    //アクセストークン
    string token = textBox2.Text;
    //送信するメッセージ
    string LINE_url = "https://notify-api.line.me/api/notify";
    Encoding enc = Encoding.UTF8;
    string payload = "message=" + HttpUtility.UrlEncode(strMsg, enc);


    using (WebClient client = new WebClient())
    {
        client.Encoding = enc;
        client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
        client.Headers.Add("Authorization", "Bearer " + token);
        //メッセージ送信
        client.UploadString(LINE_url, payload);
    }
}
```


以上です！！！


# REFERENCEs

https://learn.microsoft.com/ja-jp/dotnet/api/system.diagnostics.process?view=net-7.0

https://qiita.com/yasukotelin/items/605b9d4260a8c9ebcbeb


# さいごに

投資は自己責任！

カレンダー参加者募集してます！

https://qiita.com/advent-calendar/2022/mql

Have a good MQL Life!!!