2013-08-26T00:34:35の更新内容

programming/tips/msdos_cmd_tips/index.wiki.txt

current previous
2,7 2,7
 
${smdncms:keywords,MS-DOS,DOS,コマンドプロンプト,バッチ}
${smdncms:keywords,MS-DOS,DOS,コマンドプロンプト,バッチ}
 
${smdncms:tags,plat/win}
${smdncms:tags,plat/win}
 
${smdncms:meta,toc-amazonlivelink-keyword,books-jp,dos コマンド}
${smdncms:meta,toc-amazonlivelink-keyword,books-jp,dos コマンド}
~
MS-DOS コマンドプロンプトとバッチファイルに関するTips。 ここで紹介するものは主にWindows XP, Windows 7にて検証したもの(他のOSでは未検証)。
MS-DOS コマンドプロンプトとバッチファイルに関するTips。 ここで紹介するものはWindows XPにて検証したもの(他のOSでは未検証)。
 

        

        
 
-関連するページ
-関連するページ
 
--[[programming/netfx/msbuild]]
--[[programming/netfx/msbuild]]
447,103 447,6
 
}}
}}
 
引数は「%~番号」で取得できる。 このとき、引用符(")は取り除かれて展開される。 環境変数は展開されてから引数として渡されるので、値に空白が含まれていると引数の区切りとみなされ、別々に渡される点は注意が必要。 また、どちらのバッチファイルも同一プロセスで実行されるため、呼び先のバッチファイルでも呼び元の環境変数を参照することができる。
引数は「%~番号」で取得できる。 このとき、引用符(")は取り除かれて展開される。 環境変数は展開されてから引数として渡されるので、値に空白が含まれていると引数の区切りとみなされ、別々に渡される点は注意が必要。 また、どちらのバッチファイルも同一プロセスで実行されるため、呼び先のバッチファイルでも呼び元の環境変数を参照することができる。
 

        

        
+
*パイプとリダイレクト [#pipe_redirection]
+
**パイプ
+
&var{コマンド1};の標準出力を&var{コマンド2};の標準入力に接続するには次のようにする。
+

          
+
#code(,パイプ){{
+
コマンド1 | コマンド2
+
}}
+

          
+
次の例では、typeコマンドによってファイルの内容を標準出力に書き出し、sortコマンドの標準入力に渡すことでsource.txtの内容をソートした状態で表示している。
+

          
+
#prompt{{
+
E:\>type source.txt
+
ab
+
abcd
+
abc
+
a
+

          
+
E:\>type source.txt | sort
+
a
+
ab
+
abc
+
abcd
+
}}
+

          
+
次のように複数のコマンドを連結することができる。
+

          
+
#code(,複数のパイプ){{
+
コマンド1 | コマンド2 | コマンド3 | ...
+
}}
+

          
+
**リダイレクト
+
***標準入力
+
ファイル&var{file};の内容をコマンド&var{command};の標準入力に渡すには次のようにする。
+

          
+
#code(,標準入力のリダイレクト){{
+
command < file
+
}}
+

          
+
***標準出力
+
コマンド&var{command};が標準出力に出力する内容をファイル&var{file};に書き込むには次のようにする。
+

          
+
#code(,標準出力のリダイレクト){{
+
command > file
+
command 1> file
+
}}
+

          
+
STDOUTのハンドルを表す1は省略することができるので、``1>``は単に``>``と記述することができる。
+

          
+
***標準エラー
+
コマンド&var{command};が標準エラーに出力する内容をファイル&var{file};に書き込むには次のようにする。
+

          
+
#code(,標準エラーのリダイレクト){{
+
command 2> file
+
}}
+

          
+
標準出力の場合とは異なり、STDERRのハンドルを表す2は省略することができないので、``2>``を単に``>``と記述することはできない。
+

          
+
***標準出力・標準エラーの追記書き込み
+
標準出力・標準エラーをリダイレクトする場合、``>>``や``2>>``と記述することでリダイレクトの際に書き込まれる内容を上書きではなくファイルに追記させることができる。
+

          
+
#code(,追記モードでの標準出力のリダイレクト){{
+
command >> file
+
}}
+

          
+
#code(,追記モードでの標準エラーのリダイレクト){{
+
command 2>> file
+
}}
+

          
+
***標準入力と標準出力のリダイレクト
+
ファイルinput.txtの内容をコマンドの標準入力に渡し、コマンドの標準出力をファイルoutput.txtにリダイレクトする場合は次のようにする。
+

          
+
#code(,標準入力と標準出力のリダイレクト){{
+
command < input.txt > outout.txt
+
}}
+

          
+

          
+
***標準出力と標準エラーのリダイレクト
+
標準出力と標準エラーを別々のファイルにリダイレクトする場合は次のようにする。
+

          
+
#code(,標準出力と標準エラーを別々のファイルにリダイレクト){{
+
command > out.log 2> err.log
+
}}
+

          
+
標準出力と標準エラーを同一のファイルにリダイレクトする場合は次のようにする。
+

          
+
#code(,標準出力と標準エラーを同一のファイルにリダイレクト){{
+
command > out.log 2>&1
+
}}
+

          
+
***NULデバイス
+
UNIXの``/dev/null``に相当するものとして``nul``が用意されている。 例えば標準出力を``nul``にリダイレクトすれば出力内容はすべて破棄され、一切表示されなくなる。
+

          
+
#code(,NULデバイスへのリダイレクト){{
+
command > nul
+
}}
+

          
+

          
 
*文字コードの変更
*文字コードの変更
 
chcpコマンドを用いると、使用する文字コードを変更できる。 引数で指定できる主な文字コードは次のとおり。
chcpコマンドを用いると、使用する文字コードを変更できる。 引数で指定できる主な文字コードは次のとおり。
 
|~コード|~名称|h
|~コード|~名称|h

programming/netfx/tips/console_input_without_echo_back/index.wiki.txt

current previous
4,17 4,18
 

        

        
 
#googleadunit
#googleadunit
 

        

        
~
&msdn(netfx,member,System.Console.ReadLine){Console.ReadLineメソッド};は入力された文字列が表示(エコーバック)されてしまうため、パスワードなど入力された文字列を表示したくない場合には使えない。
&msdn(netfx,member,System.Console.ReadLine){Console.ReadLine()メソッド};は入力された文字列が表示(エコーバック)されてしまうため、パスワードなど入力された文字列を表示したくない場合には使えない。 &msdn(netfx,member,System.Console.ReadKey){ReadKey()メソッド};ではキー入力をエコーバックするかどうか指定できるため、ReadLine()メソッドの代わりに使用できる。
 

        

        
~
&msdn(netfx,member,System.Console.ReadKey){ReadKeyメソッド};は引数でキー入力をエコーバックするかどうか指定できるため、これを使うことでエコーバックせずに入力を行うようにすることができる。 ただし、ReadKeyメソッドを使用する場合はEnterやBackSpaceなどのキーが押下された場合の処理も自前で記述する必要がある。
ReadKey()メソッドを使用する場合は、ReadLine()メソッドと異なりEnterやBackSpaceなどのキーが押下された場合の処理も自前で記述する必要がある。
 

        

        
 
#code(cs,ReadKeyメソッドを使ったパスワード入力の例){{
#code(cs,ReadKeyメソッドを使ったパスワード入力の例){{
 
using System;
using System;
 
using System.Text;
using System.Text;
-
using System.Threading;
 

        

        
 
static class ConsoleUtils {
static class ConsoleUtils {
 
  /// <summary>エコーバック無しのReadLine</summary>
  /// <summary>エコーバック無しのReadLine</summary>
~
  /// <returns>入力された文字列を返す。 ESCが押された場合はその時点でnullを返す。</returns>
  /// <returns>入力された文字列、ESCが押された場合はnull</returns>
 
  public static string ReadPassword(string prompt)
  public static string ReadPassword(string prompt)
 
  {
  {
 
    // プロンプトを表示
    // プロンプトを表示
24,17 25,23
 
    var password = new StringBuilder();
    var password = new StringBuilder();
 

        

        
 
    for (;;) {
    for (;;) {
-
      // キー入力が行われるまで待機する
-
      if (!Console.KeyAvailable) {
-
        Thread.Sleep(50);
-
        continue;
-
      }
-

          
 
      // 入力されたキー情報を読む(エコーバックはしない)
      // 入力されたキー情報を読む(エコーバックはしない)
 
      var keyinfo = Console.ReadKey(true);
      var keyinfo = Console.ReadKey(true);
 

        

        
 
      switch (keyinfo.Key) {
      switch (keyinfo.Key) {
 
        case ConsoleKey.Escape:
        case ConsoleKey.Escape:
~
          // ESCキーが押された場合は、入力がキャンセルされたものとしてnullを返す
          // ESCキーが押された場合はnullを返す
 
          Console.WriteLine();
          Console.WriteLine();
 
          return null;
          return null;
 

        

        
 
        case ConsoleKey.Enter:
        case ConsoleKey.Enter:
~
          // Enterキーが押された場合は、入力が確定されたものとしてバッファに格納した文字列を返す
          // Enterキーが押された場合は、入力された文字列を返す
 
          Console.WriteLine();
          Console.WriteLine();
 
          return password.ToString();
          return password.ToString();
 

        

        
42,34 49,11
 
          // BackSpaceキーが押された場合は、バッファから最後の一文字を削除する
          // BackSpaceキーが押された場合は、バッファから最後の一文字を削除する
 
          if (0 < password.Length)
          if (0 < password.Length)
 
            password.Length -= 1;
            password.Length -= 1;
+
          else
+
            // 削除できる文字がない場合は、ビープ音を鳴らす
+
            Console.Beep();
 
          break;
          break;
 

        

        
 
        default:
        default:
~
          if (Char.IsLetter(keyinfo.KeyChar)) {
          // 入力された文字をバッファに追加
~
            // 入力された文字がアルファベットなどの文字の場合
          password.Append(keyinfo.KeyChar);
+
            if ((keyinfo.Modifiers & ConsoleModifiers.Shift) == 0) {
+
              // Shiftキーが押されていない場合は、入力された文字をそのままバッファに追加する
+
              password.Append(keyinfo.KeyChar);
+
            }
+
            else {
+
              // Shiftキーが押されている場合は、CapsLockキーの状態に応じて大文字または小文字にする
+
              if (Console.CapsLock)
+
                password.Append(Char.ToLower(keyinfo.KeyChar));
+
              else
+
                password.Append(Char.ToUpper(keyinfo.KeyChar));
+
            }
+
          }
+
          else if (!Char.IsControl(keyinfo.KeyChar)) {
+
            // 入力された文字が制御文字以外(数字や記号)の場合は、そのままバッファに追加する
+
            password.Append(keyinfo.KeyChar);
+
          }
+
          else {
+
            // コントロールキーやファンクションキーが入力された場合は、ビープ音を鳴らす
+
            Console.Beep();
+
          }
 
          break;
          break;
 
      }
      }
 
    }
    }
97,7 81,6
 
> pass.exe
> pass.exe
 
Password: 
Password: 
 
pass = hoge
pass = hoge
+

          
 
> pass.exe
> pass.exe
 
Password:     --- [途中でESCを押下した場合]
Password:     --- [途中でESCを押下した場合]
 
cancelled
cancelled
105,9 88,6
 

        

        
 
上記サンプルは.NET Framework 3.5+Windows XPおよびMono 2.4.4+Ubuntu 10.04で動作確認済み。
上記サンプルは.NET Framework 3.5+Windows XPおよびMono 2.4.4+Ubuntu 10.04で動作確認済み。
 

        

        
+
-関連するページ
+
--[[programming/netfx/standard_streams/0_console]]
+
--[[programming/netfx/string/6_securestring]]
 
-参照
-参照
 
--&msdn(netfx,id,x3h8xffw){Console.ReadKey メソッド};
--&msdn(netfx,id,x3h8xffw){Console.ReadKey メソッド};
 
--&msdn(netfx,member,System.Console.KeyAvailable){Console.KeyAvailable プロパティ};
--&msdn(netfx,member,System.Console.KeyAvailable){Console.KeyAvailable プロパティ};

programming/netfx/standard_streams/index.wiki.txt

current previous
1,10 0,0
+
${smdncms:title,標準入出力}
+
${smdncms:keywords,標準入出力,標準ストリーム,stdin,stdout,stderr,パイプ,リダイレクト}
+

          
+
ここでは.NET Frameworkにおける標準ストリーム(standard streams)の扱い方について解説します。
+

          
+
#googleadunit(banner)
+

          
+
-ページ一覧
+
#ls2_1(noroot,pathsort)
+

          

programming/netfx/standard_streams/1_process/index.wiki.txt

current previous
1,590 0,0
+
${smdncms:title,子プロセスの標準入出力}
+
${smdncms:header_title,子プロセスの標準入出力 (System.Diagnostics.Process)}
+
${smdncms:keywords,System.Diagnostics.Process,バイナリ,テキスト,送受信}
+
${smdncms:document_versions,codelang=cs,codelang=vb}
+

          
+
#navi(..)
+

          
+
&msdn(netfx,type,System.Diagnostics.Process){Processクラス};を使うことで子プロセスを起動することができます。 &msdn(netfx,type,System.Diagnostics.Process){Processクラス};には起動した子プロセスの標準ストリームをリダイレクトするためのプロパティやメソッドが用意されています。
+

          
+
&msdn(netfx,type,System.Diagnostics.ProcessStartInfo){ProcessStartInfoクラス};を使って子プロセスを起動する場合、&msdn(netfx,member,System.Diagnostics.ProcessStartInfo.UseShellExecute){UseShellExecuteプロパティ};に``false``を指定し、&msdn(netfx,member,System.Diagnostics.ProcessStartInfo.RedirectStandardOutput){RedirectStandardOutput};などのプロパティを``true``にすることで子プロセスの標準ストリームをリダイレクトさせることができます。
+

          
+
-関連するページ
+
--[[programming/netfx/stream/0_abstract]]
+
--[[programming/netfx/stream/2_streamreader_streamwriter]]
+
--[[programming/netfx/stream/3_binaryreader_binarywriter]]
+

          
+
#googleadunit
+

          
+
*標準入力への書き込み [#RedirectStandardInput]
+
子プロセスの標準入力へ書き込みを行う場合は、&msdn(netfx,member,System.Diagnostics.ProcessStartInfo.RedirectStandardInput){ProcessStartInfo.RedirectStandardInput};を``true``にして子プロセスを起動します。 その後、&msdn(netfx,member,System.Diagnostics.Process.StandardInput){Process.StandardInputプロパティ};に設定される[[StreamWriter>programming/netfx/stream/2_streamreader_streamwriter#StreamWriter]]に対して書き込みを行うことで起動した子プロセスの標準入力へ書き込むことができます。
+

          
+
なお、子プロセスの標準入力をリダイレクトする場合は&msdn(netfx,member,System.Diagnostics.ProcessStartInfo.UseShellExecute){ProcessStartInfo.UseShellExecute};を``false``にする必要があります。
+

          
+
次の例では、自プロセスparent.exeから子プロセスchild.exeを起動し、子プロセスの標準入力にテキストを書き込んでいます。 子プロセスでは、標準入力からテキストを読み込み、行番号を付けて標準出力に書き込んでいます。
+

          
+
#tabpage(codelang=cs)
+
#code(cs,parent.cs){{
+
// csc parent.cs /out:parent.exe
+
using System;
+
using System.Diagnostics;
+

          
+
class Sample {
+
  public static void Main()
+
  {
+
    // 子プロセスchild.exeの起動パラメータを作成する
+
    ProcessStartInfo psi = new ProcessStartInfo("child.exe");
+

          
+
    psi.UseShellExecute = false; // シェルを使用せず子プロセスを起動する
+
    psi.RedirectStandardInput = true; // 子プロセスの標準入力をリダイレクトする
+

          
+
    // 子プロセスを起動する
+
    using (Process child = Process.Start(psi)) {
+
      // リダイレクトした子プロセスの標準入力にテキストを書き込む
+
      child.StandardInput.WriteLine("line1");
+
      child.StandardInput.WriteLine("line2");
+
      child.StandardInput.WriteLine("line3");
+

          
+
      // 子プロセスの標準入力を閉じて書き込みを終了する
+
      child.StandardInput.Close();
+

          
+
      // 子プロセスの終了を待機する
+
      child.WaitForExit();
+
    }
+
  }
+
}
+
}}
+

          
+
#code(cs,child.cs){{
+
// csc child.cs /out:child.exe
+
using System;
+

          
+
class Sample {
+
  public static void Main()
+
  {
+
    // 標準入力から読み込んだ内容に行番号を付けて標準出力に書き込む
+
    int lineNumber = 0;
+

          
+
    while (true) {
+
      string line = Console.ReadLine();
+

          
+
      if (line == null) {
+
        break;
+
      }
+
      else {
+
        lineNumber++;
+
        Console.WriteLine("{0}: {1}", lineNumber, line);
+
      }
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code(vb,parent.vb){{
+
' vbc parent.vb /out:parent.exe
+
Imports System
+
Imports System.Diagnostics
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 子プロセスchild.exeの起動パラメータを作成する
+
    Dim psi As New ProcessStartInfo("child.exe")
+

          
+
    psi.UseShellExecute = False ' シェルを使用せず子プロセスを起動する
+
    psi.RedirectStandardInput = True ' 子プロセスの標準入力をリダイレクトする
+

          
+
    ' 子プロセスを起動する
+
    Using child As Process = Process.Start(psi)
+
      ' リダイレクトした子プロセスの標準入力にテキストを書き込む
+
      child.StandardInput.WriteLine("line1")
+
      child.StandardInput.WriteLine("line2")
+
      child.StandardInput.WriteLine("line3")
+

          
+
      ' 子プロセスの標準入力を閉じて書き込みを終了する
+
      child.StandardInput.Close()
+

          
+
      ' 子プロセスの終了を待機する
+
      child.WaitForExit()
+
    End Using
+
  End Sub
+
End Class
+
}}
+

          
+
#code(vb,child.vb){{
+
' vbc child.vb /out:parent.exe
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 標準入力から読み込んだ内容に行番号を付けて標準出力に書き込む
+
    Dim lineNumber As Integer = 0
+

          
+
    Do
+
      Dim line As String = Console.ReadLine()
+

          
+
      If line Is Nothing Then
+
        Exit Do
+
      Else
+
        lineNumber += 1
+
        Console.WriteLine("{0}: {1}", lineNumber, line)
+
      End If
+
    Loop
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
>parent.exe
+
1: line1
+
2: line2
+
3: line3
+
}}
+

          
+
child.exeでは標準入力から読み込めなくなるまで読み込みを続けるようになっているため、parent.exeの方でProcess.StandardInput.Closeメソッドを呼び出して標準入力を閉じない限りchild.exeは終了しない点に注意してください。
+

          
+
このようにして子プロセスの標準入力に書き込みを行うことができます。 子プロセスの標準入力となるProcess.StandardInputプロパティはStreamWriterであるため、[[StreamWriterのメソッド>programming/netfx/stream/2_streamreader_streamwriter#StreamWriter]]を使って書き込みを行うことができます。
+

          
+

          
+
*標準出力・標準エラーからの読み込み [#RedirectStandardOutputStandardError]
+
子プロセスの標準出力から読み込みを行う場合は、[[標準入力の場合>#RedirectStandardInput]]と同様に&msdn(netfx,member,System.Diagnostics.ProcessStartInfo.RedirectStandardOutput){ProcessStartInfo.RedirectStandardOutpout};を``true``にして子プロセスを起動します。 その後、&msdn(netfx,member,System.Diagnostics.Process.StandardOutput){Process.StandardOutputプロパティ};に設定される[[StreamReader>programming/netfx/stream/2_streamreader_streamwriter#StreamReader]]を使って読み込みを行うことで起動した子プロセスの標準出力から読み込むことができます。
+

          
+
なお、子プロセスの標準出力をリダイレクトする場合は、&msdn(netfx,member,System.Diagnostics.ProcessStartInfo.UseShellExecute){ProcessStartInfo.UseShellExecute};を``false``にする必要があります。
+

          
+
次の例では、自プロセスparent.exeから子プロセスchild.exeを起動し、子プロセスの標準出力に書き込まれるテキストを読み込んでいます。 子プロセスでは、単に標準出力に文字列を出力しています。
+

          
+
#tabpage(codelang=cs)
+
#code(cs,parent.cs){{
+
// csc parent.cs /out:parent.exe
+
using System;
+
using System.Diagnostics;
+

          
+
class Sample {
+
  public static void Main()
+
  {
+
    // 子プロセスchild.exeの起動パラメータを作成する
+
    ProcessStartInfo psi = new ProcessStartInfo("child.exe");
+

          
+
    psi.UseShellExecute = false; // シェルを使用せず子プロセスを起動する
+
    psi.RedirectStandardOutput = true; // 子プロセスの標準出力をリダイレクトする
+

          
+
    // 子プロセスを起動する
+
    using (Process child = Process.Start(psi)) {
+
      // リダイレクトした子プロセスの標準出力からテキストを読み込む
+
      string stdout = child.StandardOutput.ReadToEnd();
+

          
+
      // 子プロセスの終了を待機する
+
      child.WaitForExit();
+

          
+
      // 読み込んだテキストを表示する
+
      Console.WriteLine("<{0}>", stdout);
+
    }
+
  }
+
}
+
}}
+

          
+
#code(cs,child.cs){{
+
// csc child.cs /out:child.exe
+
using System;
+

          
+
class Sample {
+
  public static void Main()
+
  {
+
    Console.Write("Hello, world!");
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code(vb,parent.vb){{
+
' vbc parent.vb /out:parent.exe
+
Imports System
+
Imports System.Diagnostics
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 子プロセスchild.exeの起動パラメータを作成する
+
    Dim psi As New ProcessStartInfo("child.exe")
+

          
+
    psi.UseShellExecute = False ' シェルを使用せず子プロセスを起動する
+
    psi.RedirectStandardOutput = True ' 子プロセスの標準出力をリダイレクトする
+

          
+
    ' 子プロセスを起動する
+
    Using child As Process = Process.Start(psi)
+
      ' リダイレクトした子プロセスの標準出力からテキストを読み込む
+
      Dim stdout As String = child.StandardOutput.ReadToEnd()
+

          
+
      ' 子プロセスの終了を待機する
+
      child.WaitForExit()
+

          
+
      ' 読み込んだテキストを表示する
+
      Console.WriteLine("<{0}>", stdout)
+
    End Using
+
  End Sub
+
End Class
+
}}
+

          
+
#code(vb,child.vb){{
+
' vbc child.vb /out:parent.exe
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Console.Write("Hello, world!")
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
>parent.exe
+
<Hello, world!>
+
}}
+

          
+
標準エラーの場合も標準出力と同様で、&msdn(netfx,member,System.Diagnostics.ProcessStartInfo.RedirectStandardError){ProcessStartInfo.RedirectStandardError};を``true``にして子プロセスを起動し、&msdn(netfx,member,System.Diagnostics.Process.StandardError){Process.StandardErrorプロパティ};を使って標準エラーから読み込みを行います。
+

          
+
このようにして子プロセスの標準出力・標準エラーから読み込みを行うことができます。 子プロセスの標準出力・標準エラーとなるProcess.StandardOutput, StandardErrorプロパティはStreamReaderであるため、[[StreamReaderのメソッド>programming/netfx/stream/2_streamreader_streamwriter#StreamReader]]を使って読み込みを行うことができます。
+

          
+

          
+
**イベントハンドラを使った非同期読み込み
+
&msdn(netfx,member,System.Diagnostics.Process.BeginOutputReadLine){Process.BeginOutputReadLine};, &msdn(netfx,member,System.Diagnostics.Process.BeginErrorReadLine){BeginErrorReadLine};メソッドを使うと、標準出力・標準エラーに書き込まれる内容を非同期的に読み込むことができます。
+

          
+
同期的に読み込む場合と同様、&msdn(netfx,member,System.Diagnostics.ProcessStartInfo.RedirectStandardOutput){ProcessStartInfo.RedirectStandardOutpout};, &msdn(netfx,member,System.Diagnostics.ProcessStartInfo.RedirectStandardError){RedirectStandardError};を``true``にして子プロセスを起動し、読み込みを開始する時点でProcess.BeginOutputReadLine, BeginErrorReadLineメソッドを呼び出します。
+

          
+
書き込まれた内容は&msdn(netfx,member,System.Diagnostics.Process.OutputDataReceived){Process.OutputDataReceived};, &msdn(netfx,member,System.Diagnostics.Process.ErrorDataReceived){ErrorDataReceived};イベントを使うことで受信できます。 そのため、読み込みを開始する前にこれらのイベントに適切なイベントハンドラを指定しておく必要があります。 受信したデータはイベントハンドラで&msdn(netfx,member,System.Diagnostics.DataReceivedEventArgs.Data){DataReceivedEventArgs.Dataプロパティ};を参照することで得られます。 なお、このプロパティで取得できる文字列には改行文字は含まれません。
+

          
+
#tabpage(codelang=cs)
+
#code(cs,parent.cs){{
+
// csc parent.cs /out:parent.exe
+
using System;
+
using System.Diagnostics;
+

          
+
class Sample {
+
  public static void Main()
+
  {
+
    // 子プロセスを作成する
+
    using (Process child = new Process()) {
+
      // 子プロセスchild.exeの起動パラメータを設定する
+
      child.StartInfo.FileName = "child.exe";
+
      child.StartInfo.UseShellExecute = false; // シェルを使用せず子プロセスを起動する
+
      child.StartInfo.RedirectStandardOutput = true; // 子プロセスの標準出力をリダイレクトする
+
      child.StartInfo.RedirectStandardError = true; // 子プロセスの標準エラーをリダイレクトする
+

          
+
      // リダイレクトされた標準出力・標準エラーの内容を受信するイベントハンドラを設定する
+
      child.OutputDataReceived += PrintOutputData;
+
      child.ErrorDataReceived  += PrintErrorData;
+

          
+
      // 子プロセスを起動する
+
      child.Start();
+

          
+
      // 標準出力・標準エラーの非同期読み込みを開始する
+
      child.BeginOutputReadLine();
+
      child.BeginErrorReadLine();
+

          
+
      // 子プロセスの終了を待機する
+
      while (!child.WaitForExit(250)) {
+
        // 終了するまでの間、250ミリ秒毎に待機中のメッセージを表示する
+
        Console.WriteLine("(waiting)");
+
      }
+
    }
+
  }
+

          
+
  private static void PrintOutputData(object sender, DataReceivedEventArgs e)
+
  {
+
    // 子プロセスの標準出力から受信した内容を自プロセスの標準出力に書き込む
+
    Process p = (Process)sender;
+

          
+
    if (!string.IsNullOrEmpty(e.Data))
+
      Console.WriteLine("[{0};stdout] {1}", p.ProcessName, e.Data);
+
  }
+

          
+
  private static void PrintErrorData(object sender, DataReceivedEventArgs e)
+
  {
+
    // 子プロセスの標準エラーから受信した内容を自プロセスの標準エラーに書き込む
+
    Process p = (Process)sender;
+

          
+
    if (!string.IsNullOrEmpty(e.Data))
+
      Console.Error.WriteLine("[{0};stderr] {1}", p.ProcessName, e.Data);
+
  }
+
}
+
}}
+

          
+
#code(cs,child.cs){{
+
// csc child.cs /out:child.exe
+
using System;
+
using System.Threading;
+

          
+
class Sample {
+
  public static void Main()
+
  {
+
    // 一定時間おきに標準出力と標準エラーにメッセージを出力する
+
    for (int i = 0; i < 10; i++) {
+
      if (i % 2 == 0)
+
        Console.Error.WriteLine("Hello, stderr!");
+
      else
+
        Console.WriteLine("Hello, stdout!");
+

          
+
      Thread.Sleep(100);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code(vb,parent.vb){{
+
' vbc parent.vb /out:parent.exe
+
Imports System
+
Imports System.Diagnostics
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 子プロセスを作成する
+
    Using child As New Process()
+
      ' 子プロセスchild.exeの起動パラメータを設定する
+
      child.StartInfo.FileName = "child.exe"
+
      child.StartInfo.UseShellExecute = False ' シェルを使用せず子プロセスを起動する
+
      child.StartInfo.RedirectStandardOutput = True ' 子プロセスの標準出力をリダイレクトする
+
      child.StartInfo.RedirectStandardError = True ' 子プロセスの標準エラーをリダイレクトする
+

          
+
      ' リダイレクトされた標準出力・標準エラーの内容を受信するイベントハンドラを設定する
+
      AddHandler child.OutputDataReceived, AddressOf PrintOutputData
+
      AddHandler child.ErrorDataReceived, AddressOf PrintErrorData
+

          
+
      ' 子プロセスを起動する
+
      child.Start()
+

          
+
      ' 標準出力・標準エラーの非同期読み込みを開始する
+
      child.BeginOutputReadLine()
+
      child.BeginErrorReadLine()
+

          
+
      ' 子プロセスの終了を待機する
+
      Do Until child.WaitForExit(250)
+
        ' 終了するまでの間、250ミリ秒毎に待機中のメッセージを表示する
+
        Console.WriteLine("(waiting)")
+
      Loop
+
    End Using
+
  End Sub
+

          
+
  Private Shared Sub PrintOutputData(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
+
    ' 子プロセスの標準出力から受信した内容を自プロセスの標準出力に書き込む
+
    Dim p As Process = DirectCast(sender, Process)
+

          
+
    If Not String.IsNullOrEmpty(e.Data) Then
+
      Console.WriteLine("[{0};stdout] {1}", p.ProcessName, e.Data)
+
    End If
+
  End Sub
+

          
+
  Private Shared Sub PrintErrorData(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
+
    ' 子プロセスの標準エラーから受信した内容を自プロセスの標準エラーに書き込む
+
    Dim p As Process = DirectCast(sender, Process)
+

          
+
    If Not String.IsNullOrEmpty(e.Data) Then
+
      Console.Error.WriteLine("[{0};stderr] {1}", p.ProcessName, e.Data)
+
    End If
+
  End Sub
+
End Class
+
}}
+

          
+
#code(vb,child.vb){{
+
' vbc child.vb /out:parent.exe
+
Imports System
+
Imports System.Threading
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 一定時間おきに標準出力と標準エラーにメッセージを出力する
+
    For i As Integer = 0 To 9
+
      If i Mod 2 = 0 Then
+
        Console.Error.WriteLine("Hello, stderr!")
+
      Else
+
        Console.WriteLine("Hello, stdout!")
+
      End If
+

          
+
      Thread.Sleep(100)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
>parent.exe
+
[child;stderr] Hello, stderr!
+
[child;stdout] Hello, stdout!
+
[child;stderr] Hello, stderr!
+
(waiting)
+
[child;stdout] Hello, stdout!
+
[child;stderr] Hello, stderr!
+
[child;stdout] Hello, stdout!
+
(waiting)
+
[child;stderr] Hello, stderr!
+
[child;stdout] Hello, stdout!
+
(waiting)
+
[child;stderr] Hello, stderr!
+
[child;stdout] Hello, stdout!
+
}}
+

          
+
&msdn(netfx,member,System.Diagnostics.Process.CancelOutputRead){CancelOutputRead};, &msdn(netfx,member,System.Diagnostics.Process.CancelErrorRead){CancelErrorRead};メソッドを使うと、イベントハンドラでの標準出力・標準エラーの受信を中止することができます。 このメソッドを呼び出した後はイベントハンドラが呼び出されることはありませんが、標準出力・標準エラーに書き込まれる内容は破棄されず引き続きバッファリングされます。 そのため、再度BeginOutputReadLine, BeginErrorReadLineメソッドを呼び出すとバッファリングされた内容が受信されます。
+

          
+

          
+
*バイナリデータの読み書き
+
Process.StandardInput/StandardOutputプロパティは[[StreamWriter/StreamReader>programming/netfx/stream/2_streamreader_streamwriter]]であるため、バイナリ形式での読み書きを行えるようにはなっていません。 また、OutputDataReceivedイベントで受信できる内容もテキスト形式となっています。
+

          
+
子プロセスの標準入出力に対してバイナリデータの読み書きを行う場合は、StandardInput.BaseStream/StandardOutput.BaseStreamプロパティを参照して標準入出力のStreamを取得します。 取得したStreamを使って直接読み書きを行うか、取得したStreamから[[BinaryWriter/BinaryReader>programming/netfx/stream/3_binaryreader_binarywriter]]を作成することでバイナリデータの読み書きができるようになります。
+

          
+
次の例では、BinaryWriterを使って子プロセスの標準入力にバイナリデータを書き込んでいます。
+

          
+
#tabpage(codelang=cs)
+
#code(cs,parent.cs){{
+
// csc parent.cs /out:parent.exe
+
using System;
+
using System.Diagnostics;
+
using System.IO;
+

          
+
class Sample {
+
  public static void Main()
+
  {
+
    // 子プロセスchild.exeの起動パラメータを作成する
+
    ProcessStartInfo psi = new ProcessStartInfo("child.exe");
+

          
+
    psi.UseShellExecute = false; // シェルを使用せず子プロセスを起動する
+
    psi.RedirectStandardInput = true; // 子プロセスの標準入力をリダイレクトする
+

          
+
    // 子プロセスを起動する
+
    using (Process child = Process.Start(psi)) {
+
      // リダイレクトした子プロセスの標準入力に書き込むBinaryWriterを作成
+
      BinaryWriter writer = new BinaryWriter(child.StandardInput.BaseStream);
+

          
+
      // バイナリデータを書き込む
+
      writer.Write((long)0x0706050403020100);
+
      writer.Write((int)0x0b0a0908);
+
      writer.Write((short)0x0d0c);
+
      writer.Write((int)0x11223344);
+

          
+
      // 子プロセスの標準入力を閉じて書き込みを終了する
+
      child.StandardInput.Close();
+

          
+
      // 子プロセスの終了を待機する
+
      child.WaitForExit();
+
    }
+
  }
+
}
+
}}
+

          
+
#code(cs,child.cs){{
+
// csc child.cs /out:child.exe
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 標準入力から読み込んだ内容を1行8バイト毎に文字列化して表示する
+
    using (Stream stdin = Console.OpenStandardInput()) {
+
      byte[] buffer = new byte[8];
+
      int cursor = 0;
+

          
+
      for (;;) {
+
        int len = stdin.Read(buffer, 0, buffer.Length);
+

          
+
        if (len == 0)
+
          break;
+

          
+
        for (int index = 0; index < len; index++) {
+
          Console.Write("{0:X2} ", buffer[index]);
+

          
+
          cursor++;
+

          
+
          if (cursor == 8) {
+
            Console.WriteLine();
+
            cursor = 0;
+
          }
+
        }
+
      }
+
    }
+

          
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code(vb,parent.vb){{
+
' vbc parent.vb /out:parent.exe
+
Imports System
+
Imports System.Diagnostics
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 子プロセスchild.exeの起動パラメータを作成する
+
    Dim psi As New ProcessStartInfo("child.exe")
+

          
+
    psi.UseShellExecute = False ' シェルを使用せず子プロセスを起動する
+
    psi.RedirectStandardInput = True ' 子プロセスの標準入力をリダイレクトする
+

          
+
    ' 子プロセスを起動する
+
    Using child As Process = Process.Start(psi)
+
      ' リダイレクトした子プロセスの標準入力に書き込むBinaryWriterを作成
+
      Dim writer As New BinaryWriter(child.StandardInput.BaseStream)
+

          
+
      ' バイナリデータを書き込む
+
      writer.Write(&H0706050403020100L)
+
      writer.Write(&H0B0A0908I)
+
      writer.Write(&H0D0CS)
+
      writer.Write(&H11223344I)
+

          
+
      ' 子プロセスの標準入力を閉じて書き込みを終了する
+
      child.StandardInput.Close()
+

          
+
      ' 子プロセスの終了を待機する
+
      child.WaitForExit()
+
    End Using
+
  End Sub
+
End Class
+
}}
+

          
+
#code(vb,child.vb){{
+
' vbc child.vb /out:parent.exe
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 標準入力から読み込んだ内容を1行8バイト毎に文字列化して表示する
+
    Using stdin As Stream = Console.OpenStandardInput()
+
      Dim buffer(7) As Byte
+
      Dim cursor As Integer = 0
+

          
+
      Do
+
        Dim len As Integer = stdin.Read(buffer, 0, buffer.Length)
+

          
+
        If len = 0 Then Exit Do
+

          
+
        For index As Integer = 0 To len - 1
+
          Console.Write("{0:X2} ", buffer(index))
+

          
+
          cursor += 1
+

          
+
          If cursor = 8 Then
+
            Console.WriteLine()
+
            cursor = 0
+
          End If
+
        Next
+
      Loop
+
    End Using
+

          
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
>parent.exe
+
00 01 02 03 04 05 06 07 
+
08 09 0A 0B 0C 0D 44 33 
+
22 11 
+
}}
+

          
+
標準出力・標準エラーの場合も同様に、StandardOutput.BaseStream/StandardError.BaseStreamを直接扱うことでバイナリ形式での読み込みを行うことができます。
+

          
+
#navi(..)
+

          

programming/netfx/standard_streams/0_console/index.wiki.txt

current previous
1,823 0,0
+
${smdncms:title,自プロセスの標準入出力}
+
${smdncms:header_title,自プロセスの標準入出力 (System.Console)}
+
${smdncms:keywords,System.Console,Console.In,Console.Out,Console.Error}
+
${smdncms:document_versions,codelang=cs,codelang=vb}
+

          
+
#navi(..)
+

          
+
.NET Frameworkでは&msdn(netfx,type,System.Console){Consoleクラス};のメソッドを使うことで自プロセスの標準入力(stdin)や標準出力(stdout)など標準ストリーム(standard streams)に対する入出力操作を行うことができるようになっています。
+

          
+
ファイルに対する入出力を行う[[Stream>programming/netfx/stream/0_abstract]]派生クラスとして[[FileStreamクラス>programming/netfx/stream/1_1_filestream]]が存在しますが、.NET Frameworkには標準ストリームに直接対応するStream派生クラスは公開されていません。 そのかわりに、&msdn(netfx,member,System.Console.OpenStandardOutput){Console.OpenStandardOutput};などのメソッドを使って標準ストリームの[[Stream>programming/netfx/stream/0_abstract]]を取得できるため、ファイルと同様に標準ストリームを扱うこともできるようになっています。
+

          
+
-関連するページ
+
--[[programming/tips/msdos_cmd_tips#pipe_redirection]]
+
--[[programming/netfx/stream/0_abstract]]
+
--[[programming/netfx/string_formatting/0_formatstrings]]
+
--[[programming/netfx/environment/0_platform#SystemAndPlatform_NewLine]]
+
--[[programming/netfx/environment/1_process#ProcessAndAssembly_CommandLineArgs]]
+
--[[programming/netfx/environment/1_process#ProcessAndAssembly_EnvironmentVariables]]
+
--[[programming/netfx/environment/1_process#LocaleAndCulture_DefaultEncoding]]
+
--[[programming/netfx/tips/console_input_without_echo_back]]
+
--[[programming/netfx/conditional]]
+

          
+
#googleadunit
+

          
+
*標準ストリームに対する読み込み・書き込み [#Console_ReadWrite]
+
**標準出力への書き込み [#Console.WriteLine]
+
Consoleクラスのメソッド&msdn(netfx,member,System.Console.Write){Write};, &msdn(netfx,member,System.Console.WriteLine){WriteLine};などを使うことで標準出力への書き込みを行うことができます。 実際の出力先はコンソールウィンドウ、リダイレクトされたファイルやIDEの出力ペインなどとなり、アプリケーションの種類や実行環境によって変わります。
+

          
+
#tabpage(codelang=cs)
+
#code{{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    Console.Write("Hello, ");    // 改行なしで標準出力に書き込む
+
    Console.WriteLine("world!"); // 改行付きで標準出力に書き込む
+
    Console.WriteLine("Hello, world!");
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Console.Write("Hello, ")    ' 改行なしで標準出力に書き込む
+
    Console.WriteLine("world!") ' 改行付きで標準出力に書き込む
+
    Console.WriteLine("Hello, world!")
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
Hello, world!
+
Hello, world!
+
}}
+

          
+
Write, WriteLineメソッドは書式を指定した書き込みもできるようになっています。
+

          
+
#tabpage(codelang=cs)
+
#code{{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    int intValue = 42;
+
    double doubleValue = 3.141592654;
+
    DateTime dateTimeValue = new DateTime(2013, 8, 24, 1, 2, 3);
+

          
+
    // int double, DateTimeの値をそれぞれ異なる書式で出力する
+
    Console.WriteLine("{0:D4} {1:N3} {2:hh:ss}", intValue, doubleValue, dateTimeValue);
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim intValue As Integer = 42
+
    Dim doubleValue As Double = 3.141592654
+
    Dim dateTimeValue As New DateTime(2013, 8, 24, 1, 2, 3)
+

          
+
    ' Integer, Double, DateTimeの値をそれぞれ異なる書式で出力する
+
    Console.WriteLine("{0:D4} {1:N3} {2:hh:ss}", intValue, doubleValue, dateTimeValue)
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
0042 3.142 01:03
+
}}
+

          
+
書式を指定した書き込みについては[[programming/netfx/string_formatting/0_formatstrings]]で解説しています。
+

          
+

          
+
**標準入力からの読み込み [#Console.ReadLine]
+
&msdn(netfx,member,System.Console.ReadLine){ReadLineメソッド};を使うことで標準入力から1行分の文字列を読み込むことができます。
+

          
+
ReadLineメソッドの戻り値には改行文字は含まれないため、chomp/chopの操作は不要です。 ReadLineメソッドではCR/LF/CRLFのいずれかを改行として扱います。 標準入力から読み込める文字列がなくなった場合やCTRL+Z(LinuxではCTRL+D)によって入力を中断した場合、ReadLineメソッドは``null``/``Nothing``を返します。
+

          
+
#tabpage(codelang=cs,container-title=標準入力から読み込んだ内容に行番号を付けて標準出力に書き込む例)
+
#code{{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    int lineNumber = 0;
+

          
+
    while (true) { // 無限ループ
+
      // 標準入力から一行読み込む
+
      string line = Console.ReadLine();
+

          
+
      if (line == null) {
+
        // 読み込める文字列が無くなった
+
        break;
+
      }
+
      else {
+
        // 読み込んだ文字列に行番号を付けて標準出力に書き込む
+
        lineNumber++;
+
        Console.WriteLine("{0}: {1}", lineNumber, line);
+
      }
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim lineNumber As  Integer = 0
+

          
+
    While True ' 無限ループ
+
      ' 標準入力から一行読み込む
+
      Dim line As String = Console.ReadLine()
+

          
+
      If line Is Nothing Then
+
        ' 読み込める文字列が無くなった
+
        Exit While
+
      Else
+
        ' 読み込んだ文字列に行番号を付けて標準出力に書き込む
+
        lineNumber += 1
+
        Console.WriteLine("{0}: {1}", lineNumber, line)
+
      End If
+
    End While
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(キー入力を使った場合の実行例){{
+
>sample.exe
+
line1
+
1: line1
+
line2
+
2: line2
+
line3
+
3: line3
+
^Z
+
}}
+

          
+
#prompt(パイプを使った場合の実行例){{
+
>type sample.txt
+
line1
+
line2
+
line3
+

          
+
>type sample.txt | sample.exe
+
1: line1
+
2: line2
+
3: line3
+
}}
+

          
+
&msdn(netfx,member,System.Console.Read){Readメソッド};を使うと標準入力から1文字ずつ読み込むことができます。 ReadLineメソッドとは異なり、改行文字もそのまま読み込まれます。 標準入力から読み込める文字列がなくなった場合やCTRL+Zによって入力を中断した場合、Readメソッドは``-1``を返します。
+

          
+
#tabpage(codelang=cs,container-title=標準入力から1文字ずつ読み込んで標準出力に書き込む例)
+
#code{{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    while (true) { // 無限ループ
+
      // 標準入力から一文字読み込む
+
      int ch = Console.Read();
+

          
+
      if (ch == -1) {
+
        // 読み込める文字列が無くなった
+
        break;
+
      }
+
      else {
+
        // 読み込んだ文字にかっこを付けて標準出力に書き込む
+
        char c = (char)ch;
+

          
+
        Console.Write("<{0}>", c);
+
      }
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    While True ' 無限ループ
+
      ' 標準入力から一文字読み込む
+
      Dim ch As Integer = Console.Read()
+

          
+
      If ch = -1 Then
+
        ' 読み込める文字列が無くなった
+
        Exit While
+
      Else
+
        ' 読み込んだ文字にかっこを付けて標準出力に書き込む
+
        Dim c As Char = ChrW(ch)
+

          
+
        Console.Write("<{0}>", c)
+
      End If
+
    End While
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(キー入力を使った場合の実行例){{
+
>sample.exe
+
f<f>o<o>o<o>
+
<
+
>b<b>a<a>r<r>
+
<
+
>
+
^Z
+
}}
+

          
+
#prompt(パイプを使った場合の実行例){{
+
>type sample.txt
+
foo
+
bar
+

          
+
>type sample.txt | sample.exe
+
<f><o><o><
+
><b><a><r><
+
>
+
}}
+

          
+
ReadLine, Readメソッドではキー入力された文字はそのままコンソールウィンドウにも表示されます(エコーバックされる)。 キー入力を表示したくない場合、エコーバックしないようにしたい場合は&msdn(netfx,member,System.Console.ReadKey){ReadKeyメソッド};を使うことができます。 ReadKeyメソッドの使用例は[[programming/netfx/tips/console_input_without_echo_back]]をご覧ください。
+

          
+

          
+
**標準入出力のReader/Writer [#Console.In_Console.Out]
+
&msdn(netfx,member,System.Console.In){Console.Inプロパティ};や&msdn(netfx,member,System.Console.Out){Console.Outプロパティ};を使うことでも標準入出力への読み書きを行うことができます。 例えばConsole.WriteLineとConsole.Out.WriteLine、Console.ReadLineとConsole.In.ReadLineを使って標準入出力への読み書きを行えますが、どちらも結果は同じです。
+

          
+
#tabpage(codelang=cs,container-title=標準出力への書き込み)
+
#code{{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // Consoleクラスのメソッドを使って標準出力に書き込む
+
    Console.WriteLine("Hello, world!");
+

          
+
    // Console.Outプロパティを使って標準出力に書き込む
+
    Console.Out.WriteLine("Hello, world!");
+
  }
+
}
+

          
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' Consoleクラスのメソッドを使って標準出力に書き込む
+
    Console.WriteLine("Hello, world!")
+

          
+
    ' Console.Outプロパティを使って標準出力に書き込む
+
    Console.Out.WriteLine("Hello, world!")
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#tabpage(codelang=cs,container-title=標準入力からの読み込み)
+
#code{{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // Consoleクラスのメソッドを使って標準入力から読み込む
+
    string line1 = Console.ReadLine();
+

          
+
    // Console.Inプロパティを使って標準入力から読み込む
+
    string line2 = Console.In.ReadLine();
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' Consoleクラスのメソッドを使って標準入力から読み込む
+
    Dim line1 As String = Console.ReadLine()
+

          
+
    ' Console.Inプロパティを使って標準入力から読み込む
+
    Dim line2 As String = Console.In.ReadLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
Console.In/Console.Outは標準入出力への読み書きを行う[[TextReader/TextWriter>programming/netfx/stream/2_streamreader_streamwriter]]となっています。 これはJavaにおけるSystem.in/System.outに相当するものと言えます。
+

          
+
Console.Inを使った一例を挙げます。 Consoleクラスには標準入力に書き込まれる内容すべてを読み込むメソッドは存在しませんが、TextReaderには&msdn(netfx,member,System.IO.TextReader.ReadToEnd){ReadToEndメソッド};が用意されているため、これを使って標準入力の内容すべてを読み込むことができます。
+

          
+
#tabpage(codelang=cs,container-title=標準入力からの読み込み)
+
#code{{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // ReadToEndメソッドで標準入力の内容をすべて読み込む
+
    string text = Console.In.ReadToEnd();
+

          
+
    // 読み込んだ内容を出力する
+
    Console.WriteLine("(length = {0})", text.Length);
+
    Console.WriteLine(text);
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' ReadToEndメソッドで標準入力の内容をすべて読み込む
+
    Dim text As String = Console.In.ReadToEnd()
+

          
+
    ' 読み込んだ内容を出力する
+
    Console.WriteLine("(length = {0})", text.Length)
+
    Console.WriteLine(text)
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(キー入力を使った場合の実行例){{
+
>sample.exe
+
line1
+
line2
+
line3
+
^Z
+
(length = 21)
+
line1
+
line2
+
line3
+
}}
+

          
+
#prompt(パイプを使った場合の実行例){{
+
>type sample.txt
+
line1
+
line2
+
line3
+

          
+
>type sample.txt | sample.exe
+
(length = 21)
+
line1
+
line2
+
line3
+
}}
+

          
+
XmlDocumentクラスなどではTextReader/TextWriterを入力元・出力先とすることができるようになっています。 こういったクラスでは、Console.In/Console.Outを指定することで標準入出力から直接読み書きすることができるようになります。
+

          
+
#tabpage(codelang=cs,container-title=標準入出力を使ってXMLを加工する例)
+
#code{{
+
using System;
+
using System.Xml;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    XmlDocument doc = new XmlDocument();
+

          
+
    // 標準入力の内容をXMLとして読み込む
+
    doc.Load(Console.In);
+

          
+
    // ルート要素下に新しい要素を追加する
+
    doc.DocumentElement.AppendChild(doc.CreateElement("bar"))
+
                       .AppendChild(doc.CreateTextNode("bar"));
+

          
+
    // 編集したXMLを標準出力に書き込む
+
    doc.Save(Console.Out);
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.Xml
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim doc As New XmlDocument()
+

          
+
    ' 標準入力の内容をXMLとして読み込む
+
    doc.Load(Console.In)
+

          
+
    ' ルート要素下に新しい要素を追加する
+
    doc.DocumentElement.AppendChild(doc.CreateElement("bar")).AppendChild(doc.CreateTextNode("bar"))
+

          
+
    ' 編集したXMLを標準出力に書き込む
+
    doc.Save(Console.Out)
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果例){{
+
>type sample.xml
+
<?xml version="1.0" ?>
+
<doc>
+
  <foo>foo</foo>
+
</doc>
+

          
+
>type sample.xml | sample.exe
+
<?xml version="1.0"?>
+
<doc>
+
  <foo>foo</foo>
+
  <bar>bar</bar>
+
</doc>
+
}}
+

          
+
TextReader/TextWriterではなく[[Streamとして取得する>#Console_OpenStandardStream]]こともできます。
+

          
+

          
+
**標準エラー [#Console.Error]
+
[[Console.WriteLine>#Console.WriteLine]]や[[Console.ReadLine>#Console.ReadLine]]など対応するメソッドがある標準入出力とは異なり、Consoleクラスには標準エラーへの書き込みを行うメソッドは用意されていません。 標準エラーへの書き込みを行う場合は&msdn(netfx,member,System.Console.Error){Console.Errorプロパティ};を使って書き込みを行います。 Console.Errorも[[Console.Out>#Console.In_Console.Out]]と同様、標準エラーへの書き込みを行う[[TextWriter>programming/netfx/stream/2_streamreader_streamwriter]]となっています。
+

          
+
標準出力と同様、実際の出力先はコンソールウィンドウ、リダイレクトされたファイルやIDEの出力ペインなどとなり、アプリケーションの種類や実行環境によって変わります。
+

          
+
#tabpage(codelang=cs)
+
#code{{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 標準出力への書き込み
+
    Console.WriteLine("Hello, stdout!");
+
    Console.Out.WriteLine("Hello, stdout!");
+

          
+
    // 標準エラーへの書き込み
+
    Console.Error.WriteLine("Hello, stderr!");
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 標準出力への書き込み
+
    Console.WriteLine("Hello, stdout!")
+
    Console.Out.WriteLine("Hello, stdout!")
+

          
+
    ' 標準エラーへの書き込み
+
    Console.Error.WriteLine("Hello, stderr!")
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
>sample.exe
+
Hello, stdout!
+
Hello, stdout!
+
Hello, stderr!
+

          
+
>sample.exe > stdout.txt 2> stderr.txt
+

          
+
>type stdout.txt
+
Hello, stdout!
+
Hello, stdout!
+

          
+
>type stderr.txt
+
Hello, stderr!
+
}}
+

          
+

          
+
*標準ストリームの取得 [#Console_OpenStandardStream]
+
Console.In/Out/Errorは[[TextReader/TextWriter>programming/netfx/stream/2_streamreader_streamwriter]]であるためテキストデータの入出力しか行えません。 標準入出力でバイナリデータを扱いたい場合などは&msdn(netfx,member,System.Console.OpenStandardInput){OpenStandardInput};, &msdn(netfx,member,System.Console.OpenStandardOutput){OpenStandardOutput};, &msdn(netfx,member,System.Console.OpenStandardError){OpenStandardError};の各メソッドを使います。
+

          
+
これらのメソッドではそれぞれ標準入力(stdin)・標準出力(stdout)・標準エラー(stderr)に対応する[[Stream>programming/netfx/stream/0_abstract]]を取得することができます。 取得したStreamを使って直接読み書きをできるほか、取得したStreamから[[BinaryReader/BinaryWriter>programming/netfx/stream/3_binaryreader_binarywriter]]を作成してバイナリデータの読み書きを行うといったこともできます。
+

          
+
次の例では、標準入力から読み込んだ画像を水平方向に反転し、標準出力に書き込んでいます。
+

          
+
#tabpage(codelang=cs)
+
#code{{
+
using System;
+
using System.Drawing;
+
using System.Drawing.Imaging;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 標準入力のStreamを取得して画像として読み込む
+
    using (var image = new Bitmap(Console.OpenStandardInput())) {
+
      // 画像を左右反転する
+
      image.RotateFlip(RotateFlipType.RotateNoneFlipX);
+

          
+
      // 標準出力のStreamを取得して加工した画像を書き込む
+
      image.Save(Console.OpenStandardOutput(), ImageFormat.Jpeg);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.Drawing
+
Imports System.Drawing.Imaging
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 標準入力のStreamを取得して画像として読み込む
+
    Using image As New Bitmap(Console.OpenStandardInput())
+
      ' 画像を左右反転する
+
      image.RotateFlip(RotateFlipType.RotateNoneFlipX)
+

          
+
      ' 標準出力のStreamを取得して加工した画像を書き込む
+
      image.Save(Console.OpenStandardOutput(), ImageFormat.Jpeg)
+
    End Using
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行例){{
+
>sample.exe < sample.jpg > mirror.jpg
+
}}
+

          
+
OpenStandardXXXメソッドで得られるStreamをラップすることにより、暗号化や圧縮・バッファリングなどの機能を付け加えることもできます。
+

          
+
次の例ではbase64コマンドに似たプログラムを実装しています。 &msdn(netfx,type,System.Security.Cryptography.CryptoStream){CryptoStream};を使って標準入出力のStreamをラップすることにより、標準入力から読み込んだ内容をBASE64エンコード/デコードして標準出力に書き込んでいます。
+

          
+
#tabpage(codelang=cs)
+
#code{{
+
using System;
+
using System.IO;
+
using System.Security.Cryptography;
+

          
+
class Sample {
+
  static void Main(string[] args)
+
  {
+
    // コマンドライン引数に-dもしくは--decodeが指定されている場合はデコードを行う
+
    bool decode = false;
+

          
+
    foreach (string arg in args) {
+
      if (arg == "-d" || arg  == "--decode")
+
        decode = true;
+
    }
+

          
+
    Stream input, output;
+

          
+
    if (decode) {
+
      // BASE64デコードする場合
+
      input = new CryptoStream(Console.OpenStandardInput(), new FromBase64Transform(), CryptoStreamMode.Read);
+
      output = Console.OpenStandardOutput();
+
    }
+
    else {
+
      // BASE64エンコードする場合
+
      input = Console.OpenStandardInput();
+
      output = new CryptoStream(Console.OpenStandardOutput(), new ToBase64Transform(), CryptoStreamMode.Write);
+
    }
+

          
+
    input.CopyTo(output);
+

          
+
    output.Close();
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+
Imports System.Security.Cryptography
+

          
+
Class Sample
+
  Shared Sub Main(ByVal args As String())
+
    ' コマンドライン引数に-dもしくは--decodeが指定されている場合はデコードを行う
+
    Dim decode As Boolean = false
+

          
+
    For Each arg As String In args
+
      If arg = "-d" OrElse arg = "--decode" Then decode = True
+
    Next
+

          
+
    Dim input, output As Stream
+

          
+
    If decode Then
+
      ' BASE64デコードする場合
+
      input = New CryptoStream(Console.OpenStandardInput(), New FromBase64Transform(), CryptoStreamMode.Read)
+
      output = Console.OpenStandardOutput()
+
    Else
+
      ' BASE64エンコードする場合
+
      input = Console.OpenStandardInput()
+
      output = new CryptoStream(Console.OpenStandardOutput(), new ToBase64Transform(), CryptoStreamMode.Write)
+
    End If
+

          
+
    input.CopyTo(output)
+

          
+
    output.Close()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行例){{
+
>type sample.txt
+
Hello, world!
+

          
+
>type sample.txt | sample.exe
+
SGVsbG8sIHdvcmxkIQo=
+

          
+
>type sample.txt | sample.exe | sample.exe -d
+
Hello, world!
+

          
+
}}
+

          
+
取得した標準ストリームを使う例として、コマンドラインオプションで標準入力とファイル入力を切り替える例を実装している[[programming/netfx/tips/compute_md5sum#md5sum_command]]もあわせてご覧ください。
+

          
+

          
+
*標準ストリームのリダイレクト [#Console_SetStandardStream]
+
&msdn(netfx,member,System.Console.SetIn){SetIn};, &msdn(netfx,member,System.Console.SetOut){SetOut};, &msdn(netfx,member,System.Console.SetError){SetError};の各メソッドを使うと、実行時に標準ストリームを任意のTextReader/Writerへとリダイレクトすることができます。 リダイレクトを行うと、Console.WriteLineやReadLineなどのメソッドによる入出力先は指定されたTextReader/Writerへと変更されます。
+

          
+
次の例ではSetOutメソッドを使って標準出力の出力先を実行時に開いたファイルに変更しています。
+

          
+
#tabpage(codelang=cs)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // この内容はデフォルトの標準出力に書き込まれる
+
    Console.WriteLine("Hello, world!");
+

          
+
    // ファイルstdout.txtへ書き込むStreamWriterを作成する
+
    StreamWriter writer = new StreamWriter("stdout.txt");
+

          
+
    // 書き込みの度にバッファをフラッシュさせるためにAutoFlushをtrueにする
+
    writer.AutoFlush = true;
+

          
+
    // 作成したStreamWriterを標準出力の出力先にする
+
    Console.SetOut(writer);
+

          
+
    // この内容はstdout.txtに書き込まれる
+
    Console.WriteLine("こんにちは、世界!");
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' この内容はデフォルトの標準出力に書き込まれる
+
    Console.WriteLine("Hello, world!")
+

          
+
    ' ファイルstdout.txtへ書き込むStreamWriterを作成する
+
    Dim writer As New StreamWriter("stdout.txt")
+

          
+
    ' 書き込みの度にバッファをフラッシュさせるためにAutoFlushをTrueにする
+
    writer.AutoFlush = True
+

          
+
    ' 作成したStreamWriterを標準出力の出力先にする
+
    Console.SetOut(writer)
+

          
+
    ' この内容はstdout.txtに書き込まれる
+
    Console.WriteLine("こんにちは、世界!")
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
>sample.exe
+
Hello, world!
+

          
+
>type stdout.txt
+
こんにちは、世界!
+

          
+
}}
+

          
+
&msdn(netfx,member,System.IO.TextReader.Null){TextReader.Nullフィールド};や&msdn(netfx,member,System.IO.TextWriter.Null){TextWriter.Nullフィールド};を使うと、標準入出力をNULLデバイス(NUL, /dev/null)にリダイレクトするのと同様の効果が得られます。 次の例では、SetOutメソッドでTextWriter.Nullを指定することにより、標準出力を一切出力しないようにしています。
+

          
+
#tabpage(codelang=cs)
+
#code{{
+
using System;
+
using System.IO;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 標準出力の出力先をTextWriter.Nullに変更する
+
    Console.SetOut(TextWriter.Null);
+

          
+
    // この内容はTextWriter.Nullに書き込まれる(実際にはどこにも出力されない)
+
    Console.WriteLine("Hello, world!");
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.IO
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 標準出力の出力先をTextWriter.Nullに変更する
+
    Console.SetOut(TextWriter.Null)
+

          
+
    ' この内容はTextWriter.Nullに書き込まれる(実際にはどこにも出力されない)
+
    Console.WriteLine("Hello, world!")
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+

          
+
*標準ストリームがリダイレクトされているか調べる [#Console_IsStreamRedirected]
+
.NET Framework 4.5以降では、&msdn(netfx,member,System.Console.IsInputRedirected){IsInputRedirected};, &msdn(netfx,member,System.Console.IsOutputRedirected){IsOutputRedirected};, &msdn(netfx,member,System.Console.IsErrorRedirected){IsErrorRedirected};の各プロパティを参照することで自プロセスの標準ストリームがリダイレクトされているかどうかを知ることができるようになっています。
+

          
+
これらのプロパティは、コマンドラインで標準ストリームのパイプ・リダイレクトを行った場合にtrueとなるほか、SetIn, SetOut, SetErrorメソッドによってリダイレクトを行った場合もtrueとなります。
+

          
+
#tabpage(codelang=cs)
+
#code{{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 各標準ストリームがリダイレクトされているかどうかを調べる
+
    Console.WriteLine("IsInputRedirected:  {0}", Console.IsInputRedirected);
+
    Console.WriteLine("IsOutputRedirected: {0}", Console.IsOutputRedirected);
+
    Console.WriteLine("IsErrorRedirected:  {0}", Console.IsErrorRedirected);
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 各標準ストリームがリダイレクトされているかどうかを調べる
+
    Console.WriteLine("IsInputRedirected:  {0}", Console.IsInputRedirected)
+
    Console.WriteLine("IsOutputRedirected: {0}", Console.IsOutputRedirected)
+
    Console.WriteLine("IsErrorRedirected:  {0}", Console.IsErrorRedirected)
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
>sample.exe
+
IsInputRedirected:  False
+
IsOutputRedirected: False
+
IsErrorRedirected:  False
+

          
+
>type sample.txt | sample.exe
+
IsInputRedirected:  True
+
IsOutputRedirected: False
+
IsErrorRedirected:  False
+

          
+
>sample.exe | more
+
IsInputRedirected:  False
+
IsOutputRedirected: True
+
IsErrorRedirected:  False
+

          
+
>sample.exe < sample.txt
+
IsInputRedirected:  True
+
IsOutputRedirected: False
+
IsErrorRedirected:  False
+

          
+
>sample.exe > stdout.txt
+

          
+
>type stdout.txt
+
IsInputRedirected:  False
+
IsOutputRedirected: True
+
IsErrorRedirected:  False
+

          
+
>test.exe 2> stderr.txt
+
IsInputRedirected:  False
+
IsOutputRedirected: False
+
IsErrorRedirected:  True
+
}}
+

          
+
これらのプロパティをチェックすることで標準出力の出力先がコンソールウィンドウかどうかを知ることができるため、リダイレクトされているときは&msdn(netfx,member,System.Console.ForegroundColor){Console.ForegroundColor};/&msdn(netfx,member,System.Console.BackgroundColor){BackgroundColor};プロパティで文字色を変えたり、&msdn(netfx,member,System.Console.CursorLeft){Console.CursorLeft};/&msdn(netfx,member,System.Console.CursorTop){CursorTop};プロパティでカーソルの位置を変えたりしないようにする、といったことができます。
+

          
+
.NET Framework 4.5より前のバージョンではこれらのプロパティは用意されないため、[[c# - How to detect if Console.In (stdin) has been redirected? - Stack Overflow:http://stackoverflow.com/questions/3453220/how-to-detect-if-console-in-stdin-has-been-redirected]]で提示されているような方法を使って調べる必要があります。
+

          
+

          
+
#navi(..)
+