トイレ行ってる時間計測するヤツ

ロック～アンロック間＝トイレ離席時間とする

##### 環境
・Windows10
・VisualStudio 2017
・コマンドプロンプト
・PowerShell ver.5.1.18362.628

##### 構成
・batch_act.exe
・GetEventLog.bat
・GetEventLog.ps1

##### 生成物
・windowsログ

##### 動作手順
1.bat起動（管理者権限）、windowsログ生成
2.exe起動
3.生成ログファイル名入力、整形データ表示

##### 画面イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365607/55085134-6cf3-51aa-feca-1f63f8b3de83.png)


##### コード

```csharp:batch_act.cs
private void Batch_Act(string fileName)
		{

			// 入力値が正常かチェック
			if (FileName_IsError(fileName) == 1) return;
			
			string filePath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
							+ "\\" + this.textBox1.Text;

			// 読み込むファイルの存在確認
			if (!File.Exists(filePath))
			{
				textBox1.BackColor = Color.LemonChiffon;
				return;
			}

			List<string> outputData = new List<string>();

			// ファイル読み込み
			using (StreamReader sr = new StreamReader(filePath, Encoding.GetEncoding("UTF-8")))
			{

				string readText = sr.ReadToEnd();
				string[] splitReadText = readText.Split(new string[] { "\r\n" }, StringSplitOptions.None);
				List<string> logData = new List<string>(splitReadText);
				logData.RemoveRange(0,3);

				// データをロック・アンロックでわける
				List<string> lockData = new List<string>();
				List<string> unlockData = new List<string>();
				foreach (string dataLine in logData)
				{

					if (dataLine.EndsWith("4800"))
					{
						lockData.Add(dataLine);
					}
					if (dataLine.EndsWith("4801"))
					{
						unlockData.Add(dataLine);
					}
				}

				// 組み合わせのロック開始～アンロックの時間を算出
				int dataCount = Math.Min(lockData.Count(), unlockData.Count());
				for (int i = 0; i < dataCount; i++)
				{

					string[] splitLockData = lockData[i].Split(' ');
					string[] splitUnockData = unlockData[i].Split(' ');

					TimeSpan processTime = Convert.ToDateTime(splitUnockData[1])
											- Convert.ToDateTime(splitLockData[1]);
					string[] hhmmss = processTime.ToString().Split(':');
					
					outputData.Add(string.Concat(splitLockData[0], " ",
													splitLockData[1], " から\t"
													, hhmmss[0], " 時間 "
													, hhmmss[1], " 分 "
													, hhmmss[2], " 秒"));
				}
			}

			// 保持したデータを画面に出力
			foreach(string data in outputData)
			{
				if (data == string.Empty) continue;
				this.textBox2.Text += string.Concat(data, "\r\n");
			}

			this.textBox2.Text += "-----------------------------------------------\r\n";

		}

		private int FileName_IsError(string fileName)
		{
			if (!fileName.EndsWith(".txt")) return 1;
			if (fileName == ".txt") return 1;
			return 0;
		}
```

```bat:GetEventLog.bat
cd %~dp0

powershell -ExecutionPolicy RemoteSigned -command Set-ExecutionPolicy RemoteSigned
powershell -command .\GetEventLog.ps1
powershell Set-ExecutionPolicy Restricted

cmd

```

```powershell:GetEventLog.ps1
$path = [Environment]::GetFolderPath("Desktop") + "\eventLog.txt"

Get-EventLog Security -After (Get-Date).AddDays(-7)|`
 Where-Object {$_.EventID -in @(4800, 4801)} |`
 Select-Object -Property TimeWritten, EventId |`
 Out-File -FilePath $path
```

##### 簡易解説
batch_act.cs
テキストボックスからファイル名取得、必要箇所だけに整形して画面出力

GetEventLog.bat
自ファイルのディレクトリに移動してPowerShell起動、権限付与してGetEventLog.ps1起動

GetEventLog.ps1
Get-EventLogで、windowsログのセキュリティのデータ取得
条件は 7日前～現在、かつ eventID = 4800, 4801 (ロック・アンロック)
「日付と時刻」「イベントID」のみ取得し$pathに出力


##### 改善点
・GetEventLog.ps1の動作が遅いので取得するデータを対象データのみに絞りたかったが方法がわからななかった
（Where-Objectで絞っても動作が遅いので恐らくGet-EventLog直下で絞る必要があるが、-Newest、-Afterでも余分なデータを一度取得してしまう）
・batとPowerShellだけでtxt出力するようにしたかった