Đọc đầu vào bảng điều khiển khó, bạn cần xử lý các phím đặc biệt như Ctrl, Alt, cũng như phím con trỏ và Xóa lùi / Xóa. Trên một số bố cục bàn phím, như Ctrl Thụy Điển thậm chí còn cần thiết để nhập các phím tồn tại trực tiếp trên bàn phím Hoa Kỳ. Tôi tin rằng cố gắng xử lý việc này bằng cách sử dụng "cấp thấp"Console.ReadKey(true)
là rất khó, vì vậy cách dễ nhất và mạnh mẽ nhất là chỉ vô hiệu hóa "tiếng vang đầu vào của bàn điều khiển" trong khi nhập mật khẩu bằng một chút WINAPI.
Mẫu dưới đây dựa trên câu trả lời Đọc mật khẩu từ câu hỏi std :: cin .
private enum StdHandle
{
Input = -10,
Output = -11,
Error = -12,
}
private enum ConsoleMode
{
ENABLE_ECHO_INPUT = 4
}
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetStdHandle(StdHandle nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out int lpMode);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetConsoleMode(IntPtr hConsoleHandle, int dwMode);
public static string ReadPassword()
{
IntPtr stdInputHandle = GetStdHandle(StdHandle.Input);
if (stdInputHandle == IntPtr.Zero)
{
throw new InvalidOperationException("No console input");
}
int previousConsoleMode;
if (!GetConsoleMode(stdInputHandle , out previousConsoleMode))
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not get console mode.");
}
// disable console input echo
if (!SetConsoleMode(stdInputHandle , previousConsoleMode & ~(int)ConsoleMode.ENABLE_ECHO_INPUT))
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not disable console input echo.");
}
// just read the password using standard Console.ReadLine()
string password = Console.ReadLine();
// reset console mode to previous
if (!SetConsoleMode(stdInputHandle , previousConsoleMode))
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not reset console mode.");
}
return password;
}