Mask Password Input in a Console App
I am writing a console application using BDE 2006 and I want it to be able 开发者_开发技巧to prompt for a password string and mask it with "*" as the user is typing. I have looked around but I could not find examples of how to do this. Everything I saw was how to do this in TEdit. Any pointers on how to accomplish this?
Thanks in advance,
Nic
Here's a working solution:
program Project2;
{$APPTYPE CONSOLE}
uses
SysUtils, Windows;
function GetPassword(const InputMask: Char = '*'): string;
var
OldMode: Cardinal;
c: char;
begin
GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), OldMode);
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), OldMode and not (ENABLE_LINE_INPUT or ENABLE_ECHO_INPUT));
try
while not Eof do
begin
Read(c);
if c = #13 then // Carriage Return
Break;
Result := Result + c;
if c = #8 then // Back Space
Write(#8)
else
Write(InputMask);
end;
finally
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), OldMode);
end;
end;
begin
try
Writeln(Format(sLineBreak + 'pswd=%s',[GetPassword]));
Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Update: Note that the above code handles the BackSpaces visually, but keeps them embedded in the password, which might not be what you want.
In that case the following code would filter them out:
if c = #13 then // Carriage Return
Break;
if (c = #8) and (Length(Result) > 0) then // Back Space
begin
Delete(Result, Length(Result), 1);
Write(#8);
end
else
begin
Result := Result + c;
Write(InputMask);
end;
I have a unit with procedure ConsoleGetPassword(const caption: String; var Password: string);
which does what you want
see http://gist.github.com/570659
This works.
program Project2;
{$APPTYPE CONSOLE}
uses
SysUtils, Windows;
const
BUF_LEN = 1024;
var
amt, i, cmode: cardinal;
buf: packed array[0..BUF_LEN - 1] of char;
begin
try
Write('Enter password: ');
GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), cmode);
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), cmode and not ENABLE_ECHO_INPUT);
ReadConsole(GetStdHandle(STD_INPUT_HANDLE), @buf[0], BUF_LEN, amt, nil);
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), cmode);
Writeln;
Writeln;
Writeln('You entered: ');
for i := 0 to amt - 3 do
Write(buf[i]);
Writeln;
Writeln;
Writeln('Done');
Readln;
except
on E:Exception do
begin
Writeln(E.Classname, ': ', E.Message);
Readln;
end;
end;
end.
Please see this article on CodeProject, it may be in C#, but it does give you the right clues and the direction to take, involving ReadConsoleInput and WriteConsole API
精彩评论