2010-08-18T02:55:27の更新内容

programming/tips/console_input_without_echo_back/index.wiki.txt

current previous
1,92 0,0
+
${smdncms:title,エコーバックせずに文字列を入力する(Console.ReadKey)}
+
${smdncms:keywords,C#,エコーバック,表示しない,Console,ReadLine,ReadKey}
+
${smdncms:tags,api/.net,lang/c#}
+
Console.ReadLine()メソッドは入力された文字列が表示(エコーバック)されてしまうため、パスワードなど入力された文字列を表示したくない場合には使えない。 ReadKey()メソッドではキー入力をエコーバックするかどうか指定できるため、ReadLine()メソッドの代わりに使用できる。
+

          
+
ReadKey()メソッドを使用する場合は、ReadLine()メソッドと異なりEnterやBackSpaceなどのキーが押下された場合の処理も自前で記述する必要がある。
+

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

          
+
static class ConsoleUtils {
+
  /// <summary>エコーバック無しのReadLine</summary>
+
  /// <returns>入力された文字列、ESCが押された場合はnull</returns>
+
  public static string ReadPassword(string prompt)
+
  {
+
    // プロンプトを表示
+
    Console.Write(prompt);
+

          
+
    // 入力された文字を格納するためのバッファを用意
+
    var password = new StringBuilder();
+

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

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

          
+
      switch (keyinfo.Key) {
+
        case ConsoleKey.Escape:
+
          // ESCキーが押された場合はnullを返す
+
          Console.WriteLine();
+
          return null;
+

          
+
        case ConsoleKey.Enter:
+
          // Enterキーが押された場合は、入力された文字列を返す
+
          Console.WriteLine();
+
          return password.ToString();
+

          
+
        case ConsoleKey.Backspace:
+
          // BackSpaceキーが押された場合は、バッファから最後の一文字を削除する
+
          if (0 < password.Length)
+
            password.Length -= 1;
+
          break;
+

          
+
        default:
+
          // 入力された文字をバッファに追加
+
          password.Append(keyinfo.KeyChar);
+
          break;
+
      }
+
    }
+
  }
+

          
+
  public static void Main()
+
  {
+
    var pass = ReadPassword("Password: ");
+

          
+
    if (pass == null) {
+
      var prevColor = Console.ForegroundColor;
+

          
+
      Console.ForegroundColor = ConsoleColor.Red;
+
      Console.WriteLine("cancelled");
+
      Console.ForegroundColor = prevColor;
+
    }
+
    else {
+
      Console.WriteLine("pass = {0}", pass);
+
    }
+
  }
+
}
+
}}
+

          
+
#prompt(実行例){{
+
> pass.exe
+
Password: 
+
pass = hoge
+
> pass.exe
+
Password:     --- [途中でESCを押下した場合]
+
cancelled
+
}}
+

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

          
+
-参照
+
--&msdn(netfx,id,x3h8xffw){Console.ReadKey メソッド};
+
--&msdn(netfx,member,System.Console.KeyAvailable){Console.KeyAvailable プロパティ};
+
--[[Console class (Java Platform SE 6):http://download.oracle.com/javase/6/docs/api/java/io/Console.html]] 上記サンプルと同様のメソッド Console.readPasswordが用意されている
+