Processクラス

プロパティ

プロパティ  
System.IO.StreamWriter StandardInput 標準入力ストリームへ書き込めるStreamWriter
System.IO.StreamReader StandardOutput 標準出力ストリームを読み取れるStreamReader
System.IO.StreamReader StandardError 標準エラー ストリームを読み取れるStreamReader
System.Diagnostics.ProcessStartInfo StartInfo  
プロパティ - Process Class (System.Diagnostics) | Microsoft Docs

メソッド

   
   
方法 - Process Class (System.Diagnostics) | Microsoft Docs

Start

プロセス リソースを起動し、それをProcessコンポーネントに関連付けられます。

引数を取らない定義では、情報をStartInfoプロパティで事前に設定しておきます。

public bool Start ();
public static Process Start(
    string fileName, // プロセスで実行する文書、またはアプリケーション ファイルの名前
)
Process.Start メソッド (String) (System.Diagnostics) | MSDN
public static Process Start(
    string fileName, // プロセスで実行するアプリケーション ファイルの名前
    string arguments // プロセスに渡すコマンドライン引数
)
Process.Start メソッド (String, String) (System.Diagnostics) | MSDN
Process.Start("sample.txt");
Process.Start("notepad.exe");

出力の取得

Process process = new Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;

process.StartInfo.FileName = "sample.exe";
process.StartInfo.Arguments = "/all";

process.Start();
string output = process.StandardOutput.ReadToEnd();

Console.Write(output);
例 - Process.StandardOutput プロパティ (System.Diagnostics) | MSDN

出力が空文字列となる場合にはStartInfo.RedirectStandardErrorをtrueとして、標準エラー出力を確認します。

プロセスが接続を閉じないとき、ReadToEnd()で出力を読み込むと無期限にブロックされます。

非同期 読み取り

StandardOutputからの読み取りは同期で処理されるため、プロセスが書き込みを完了するまで処理は戻りません。この問題は、読み取りを非同期にすることで解決できます。それにはOutputDataReceivedイベントにハンドラを設定し、BeginOutputReadLine()で読み取りを開始します。

Process process = new Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += delegate (object sender, DataReceivedEventArgs e)
{
    string output = e.Data;
    Console.Write(output);
};

process.StartInfo.FileName = filename;
process.StartInfo.Arguments = arguments;

process.Start();
process.BeginOutputReadLine();

process.WaitForExit(1000);
process.Close();

プロセスが接続を閉じないとき、引数なしのWaitForExit()で待機すると無期限にブロックされます。c# - ProcessStartInfo hanging on "WaitForExit"? Why? - Stack Overflow

プロセス間通信 (inter-process communication)

  • 匿名パイプ (Anonymous pipes)
    • ローカル コンピューターでの、プロセス間通信
    • 一方向であり、ネットワーク経由では使用できない
    • 名前付きパイプと比較してオーバーヘッドは小さいが、提供するサービスも限定
    • 1つのサーバー インスタンスのみをサポート
    • スレッド間または親子のプロセス間での通信に有用
  • 名前付きパイプ (Named pipes)
    • パイプ サーバーとパイプ クライアントとの間での、プロセス間通信
    • 一方向または双方向のパイプを使用できる
    • メッセージ ベースの通信をサポートし、複数のクライアントが同じパイプ名を使用してサーバーに対して同時に接続できる
    • 偽装をサポートし、プロセス間接続においてリモート サーバー上で独自のアクセス許可を使用できる

匿名パイプ (Anonymous pipes)

Client側

static void Main(string[] args)
{
    if (args.Length == 0) return;

    using (PipeStream pipeClient
        = new AnonymousPipeClientStream(PipeDirection.In, args[0]))
    {
        using (StreamReader sr = new StreamReader(pipeClient))
        {
            string data = sr.ReadLine();
            Console.WriteLine(data);
        }
    }
}

Server側

static void Main(string[] args)
{
    Process pipeClient = new Process();
    pipeClient.StartInfo.FileName = "Client.exe";

    using (AnonymousPipeServerStream pipeServer
        = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable))
    {
        // このプロセスへのハンドルを、クライアントに渡す
        pipeClient.StartInfo.Arguments = pipeServer.GetClientHandleAsString();
        pipeClient.StartInfo.UseShellExecute = false;
        pipeClient.Start();

        pipeServer.DisposeLocalCopyOfClientHandle();

        using (StreamWriter sw = new StreamWriter(pipeServer))
        {
            sw.AutoFlush = true;
            sw.WriteLine("TEST");

            pipeServer.WaitForPipeDrain();
        }
    }

    pipeClient.WaitForExit();
    pipeClient.Close();
}
方法: ローカルのプロセス間通信で匿名パイプを使用する | Microsoft Docs

名前付きパイプ (Named pipes)

方法: ネットワークのプロセス間通信で名前付きパイプを使用する | Microsoft Docs
MSDN (Microsoft Developer Network) から検索