UE4ゲーム実行ファイルを外部から実行して停止する #UE4Study

# UE4ゲーム実行ファイルを外部から実行して停止する 

## UE4の空プロジェクトを作成して、パッケージ化

UE4の空プロジェクトを作成して、Windows(64bit)でパッケージ化する
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/782165f0-633c-26a8-bc72-748c8766a70d.png)


## C#のコマンドラインプロジェクトを作成

```csharp:Program.cs

using System.Diagnostics;

namespace UE4ProcessManager
{
    class Program
    {
        static void Main(string[] args)
        {
            string ue4ExePath = @"UE4Exeのフルパス";

            // UE4exeを起動する
            ProcessStartInfo psUE4Exe = new ProcessStartInfo();
            psUE4Exe.FileName = ue4ExePath;

            Process ps = System.Diagnostics.Process.Start(psUE4Exe);

            // 5秒後間スリープ
            System.Threading.Thread.Sleep(5000);

            // プロセスを殺す
            ps.Kill();
        }
    }
}

```

実行してみたが、UE4実行ファイルのプロセスを殺すことが出来ない
タスクマネージャーをみるとUE4Gameとなっている
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/f9810e9c-76dc-8854-fd9f-d3b8dcdccb0d.png)

UE4Game.exeを出力先に見つけることができた
(出力先)/WindowsNoEditor/Engine/Binaries/Win64
UE4Game.exe
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/d55ce83f-ee7a-54fc-3b6d-d38aa0dd3780.png)


出力先のexeは実行すると、Engine/Binaries/Win64下のUE4Game.exeを実行するようだ
ならUEGame.exeを実行してプロセスを殺せばいいかと思うが、実行するとクラッシュしてしまう
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/9887f59a-741c-10cf-4155-4f01b8a18c0d.png)


## UE4Game.exeのプロセスをkillするように修正する
```csharp:Program.cs

using System.Diagnostics;

namespace UE4ProcessManager
{
    class Program
    {
        static void Main(string[] args)
        {
            string ue4ExePath = @"UE4Exeのフルパス";
            string killProcessName = "UE4Game";

            // UE4exeを起動する
            ProcessStartInfo psUE4Exe = new ProcessStartInfo();
            psUE4Exe.FileName = ue4ExePath;

            System.Diagnostics.Process.Start(psUE4Exe);

            // 10秒後間スリープ
            System.Threading.Thread.Sleep(1000 * 10);

            // UE4Gameに一致するプロセスを殺す
            System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcessesByName(killProcessName);
            foreach (System.Diagnostics.Process p in ps)
            {
                p.Kill();
            }
        }
    }
}

```


親のプロセスを確認してからkillする場合

```csharp:Program.cs
using System;
using System.Diagnostics;
using System.IO;
using System.Management;

namespace UE4ProcessManager
{
    class Program
    {
        static void Main(string[] args)
        {
            string ue4ExePath = @"UE4Exeのフルパス";
            string killProcessName = "UE4Game";

            // UE4exeを起動する
            ProcessStartInfo psUE4Exe = new ProcessStartInfo();
            psUE4Exe.FileName = ue4ExePath;

            System.Diagnostics.Process.Start(psUE4Exe);

            // 10秒後間スリープ
            System.Threading.Thread.Sleep(1000 * 10);

            // UE4Gameに一致するプロセスを殺す
            System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcessesByName(killProcessName);
            foreach (System.Diagnostics.Process p in ps)
            {
                string parentProcessName = GetParentModuleName(p.Id);
                if(parentProcessName == Path.GetFileNameWithoutExtension(ue4ExePath))
                {
                    p.Kill();
                    break;
                }
            }
        }

        private static string GetParentModuleName(int id)
        {
            return Process.GetProcessById((int)GetParentProcessId(id)).ProcessName;
        }

        private static string GetParentArguments(int id)
        {
            return Process.GetProcessById((int)GetParentProcessId(id)).StartInfo.Arguments;
        }

        private static uint GetParentProcessId(int id)
        {
            var query = string.Format("SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {0}", id);

            using (var search = new ManagementObjectSearcher(@"root\CIMV2", query))
            //クエリから結果を取得
            using (var results = search.Get().GetEnumerator())
            {

                if (!results.MoveNext()) throw new ApplicationException("Couldn't Get ParrentProcessId.");

                var queryResult = results.Current;
                //親プロセスのPIDを取得
                return (uint)queryResult["ParentProcessId"];
            }
        }
    }
}

```

## Shippingに変更するとexe名も変わる
Settings -> Project Settings
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/47b5b825-cf23-4549-ff4d-4e3a495ebdf6.png)

Packaging -> Shippingに変更
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/15c8ed1d-dfab-cdb4-853c-d872247744e3.png)

PackageをWindows 64bitで書き出し
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/782165f0-633c-26a8-bc72-748c8766a70d.png)

UE4Game-Win64-Shipping.exeに実行ファイル名が変わっているので、プロセスがkill出来なかった時はEngine/Binaries/Win64下を要確認
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/12fa83bd-ffbe-0cbc-aa33-4499dd8e174f.png)


## 参照URL

【C#】指定した名前またはIDのプロセスを取得する
http://www.openreference.org/articles/view/567


[C#]親プロセスの情報を取得する
http://outofmem.tumblr.com/post/65659282243/c%E8%A6%AA%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%81%AE%E6%83%85%E5%A0%B1%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B