Jump to content
JackT

Trying to hide keyboard input in a console program

Recommended Posts

I am trying to hide console input when a user has to enter a password in a command prompt window.

I had the bright idea of redirecting the output of the command prompt to the NUL file but this code does not work even though you can execute the function without error.

I am sure there used to be an easy way to do this!

Do forget to include windows in the uses clause.

 

Thanks for any help in advance Jack T

  function GetPassWordInput:String;
  var
  C:Char;
  S:String;
  H,HNULL:Cardinal;
  B:BOOL;
  begin
  HNULL := CreateFile('NUL',GENERIC_WRITE,FILE_SHARE_WRITE,nil, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM,0);
  Assert(HNULL <> 0,'CREATING NUL FILE FAILED');
  H:= GetStdHandle(STD_OUTPUT_HANDLE);
      B:=SetStdHandle(STD_OUTPUT_HANDLE,HNULL);
      Assert(B,'Set standhard handle failed to assign HNULL');
      try
      begin
    repeat
     Read(C);
      if C=#8 then
     begin
      if Length(S)>1 then
      begin
        S:=LeftStr(S,Length(S)-1);
      end;
     end
     else
      if C<>#13 then
      begin
        S:=S+C;
      end;
    until C=#13;
    end
    finally
    begin
     SetStdHandle(STD_OUTPUT_HANDLE,H);
     CloseHandle(HNULL);
    end;
    end;
    Result := S;
  end;

 

Share this post


Link to post

Hi I found a solution on stack overflow.

 

https://stackoverflow.com/questions/3671042/mask-password-input-in-a-console-app

 

I improved the function so it deletes it's input if you back space

 

   function GetPassword(const InputMask: Char = '*'): string;
var
  OldMode: Cardinal;
  c: char;
  I,L:Integer;
begin
  GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), OldMode);
  SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), OldMode and not (ENABLE_LINE_INPUT or ENABLE_ECHO_INPUT));
    I:=0;
  try
    while not Eof do
    begin
      Read(c);
      if c = #8 then
      begin
        L:=Length(Result);
        if L>0 then
        begin
          Write(#8' '#8);
          Result := LeftStr(Result,L-1);
          continue;
        end;
      end
      else
      if C=#13 then
      begin
        break;
      end
      else
      begin
        Result := Result + C;
        Write(InputMask);
      end;

    end;
  finally
    SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), OldMode);
  end;
end;

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×