アプリケーションの標準出力をテキストファイルに出力してみた(2)

どもです。

前回は、「プロセスの標準出力をファイルに出力する方法」を書きました。その最後に、

実は、やりたいことは別にある。

と書きました。この「やりたいこと」は、

標準入力の内容もファイルに出力したい

です。

コンソールアプリケーションなどで、実行中にユーザに対して何か入力を求める、入力を受け付ける場合があります。これには、前回紹介した方法では対応できません。なぜなら、「標準入力の内容を受け取る」ことに対応していないためです。

今回は、この「標準入力の内容を受け取る」という内容について書いていきます。

0. 作業環境

今回のエントリでは、以下の環境で作業を行います。

開発環境
項目 内容
OS Windows10 Pro(22H2)
CPU i7-8700
メモリ 16GB
IDE Visual Studio Commnuity 2022(64bit)
version 17.3.6

1.方法

やってみた方法ですが、前回同様、実にありふれた方法です。すなわち、

  1. 別プロセスの標準入力への書込み、有効に設定する。
  2. 別プロセスの起動元で、標準入力を読み出す。
  3. 別プロセスの標準入力に、読み出した入力内容を書き込む。

という方法です。

2. 実際にやってみた

先に挙げた方法を、1つ1つ順番に実装していきます。

2.1. 別プロセスの標準入力への書込み、有効に設定する。

「別プロセスの標準入力への書込みを有効」にするためには、対象プロセスの“StartUpInfo”、すなわち“StartInfo"プロパティの中の“RedirectStandardInput"プロパティをTRUEに設定すればOKです。

具体的には、前回の実装に対して、対応する処理を追加します。追加した後の処理は、以下のようになります。

class ProcessRunner : AOutputProcRunner
{
	protected virtual void SetupStartInfo(string procName, string procArgs)
	{
		_procStartInfo = new ProcessStartInfo()
		{
			FileName = procName,
			UseShellExecute = false,
			RedirectStandardInput = TRUE,	//この処理を追加
			RedirectStandardOutput = TRUE
		};
	}
}

2.2. 別プロセスの起動元で、標準入力を読み出す。

起動元プロセスにおいて、標準入力(要は「ユーザ入力」)を読み出します。これには、(今回は)「Console.ReadKey」を使用します。

該当するコードは、後ほど紹介しますので、ここでは省略します。

2.3. 別プロセスの標準入力に、読み出した入力内容を書き込む

次に、「別プロセスの標準入力に、読み出した入力内容を書き込む」処理です。

この処理は、いくつかのポイントがあります。それは、

  1. 「別プロセスの標準入力」の取得
  2. 「入力内容」の取得
  3. 別プロセスの標準入力に、読み出した入力内容を書き込む。

です。

2.3.1. 「別プロセスの標準入力」の取得

「別プロセスの標準入力」とは、「標準入力に入力された内容」ではなく、「標準入力の『ストリーム』」のことです。「標準入力のストリーム」オブジェクトは、別プロセスの“StandardInput"プロパティが対応します。従って、“StandardInput"にアクセスすることで、「別プロセスの標準入力」オブジェクトを取得できます。

2.3.2. 「入力内容」の取得

標準入力への「入力内容の取得」は、特に課題にする内容はありません。Consoleクラスの「ReadKey」メソッドを使用することで、ユーザが押したキーの情報を取得できます。

2.3.3. 別プロセスの標準入力に、読み出した入力内容を書き込む

別プロセスの標準入力へのキーの情報の送信は、「標準入力の『ストリーム』」の“Write"メソッドで行います。

2.3.4. 実装

これらの内容をまとめた実装は、以下のようになります。

using (var stdin = proc.StandardInput)			//「別プロセスの標準入力」の取得
{
	do
	{
		var inputData = Console.ReadKey();	//「入力内容」の取得
		if (Environment.NewLine.Contains(inputData.KeyChar))
		{
			stdin.WriteLine();
		}
		else
		{
			stdin.Write(inputData.KeyChar);	//読み出した入力内容を書き込む
		}
	} while (true == _isContinue);
}

上記のコードは、必要な部分のみを抜き出しています。実際のコード量は、もう少し処理は多くなります。

「別プロセスの標準入力に、読み出した入力内容を書き込む」ためのポイントに対応する処理は、コード内のコメントとして記載しています。

先述の説明に無かった処理としては、

if (Environment.NewLine.Contains(inputData.KeyChar))
{
	stdin.WriteLine();
}

です。環境によって、改行コードは異なります。そのため、現在の設定に該当するキーが押された、キー入力があった場合に、この違いを吸収する目的の処理です。

3. まとめ

今回は、別プロセスの標準入力への書き込み方法について書きました。

書いた方法自体は、実のところ新しい内容はなく、(ネット上で)ありふれた方法になります。そのため、詳細は省略しています。

ではっ!

Ex. つづけます!

前回の最後でも書いたように、「実はやりたいこと」を今回のエントリでも書けていません。2回では完了できませんでした。そのため、もう少し書き続けます。

できれば、次回で完結(?)させたい…。