Console.ReadLineメソッドは入力された文字列が表示(エコーバック)されてしまうため、パスワードなど入力された文字列を表示したくない場合には使えない。
ReadKeyメソッドは引数でキー入力をエコーバックするかどうか指定できるため、これを使うことでエコーバックせずに入力を行うようにすることができる。 ただし、ReadKeyメソッドを使用する場合はEnterやBackSpaceなどのキーが押下された場合の処理も自前で記述する必要がある。
ReadKeyメソッドを使ったパスワード入力の例
using System;
using System.Text;
static class ConsoleUtils {
/// <summary>エコーバック無しのReadLine</summary>
/// <returns>入力された文字列を返す。 ESCが押された場合はその時点でnullを返す。</returns>
public static string ReadPassword(string prompt)
{
// プロンプトを表示
Console.Write(prompt);
// 入力された文字を格納するためのバッファを用意
var password = new StringBuilder();
for (;;) {
// 入力されたキー情報を読む(エコーバックはしない)
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;
else
// 削除できる文字がない場合は、ビープ音を鳴らす
Console.Beep();
break;
default:
if (Char.IsLetter(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;
}
}
}
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);
}
}
}
実行例
> pass.exe Password: pass = hoge > pass.exe Password: --- [途中でESCを押下した場合] cancelled
上記サンプルは.NET Framework 3.5+Windows XPおよびMono 2.4.4+Ubuntu 10.04で動作確認済み。