17

How do you get the currently logged in username in a Firemonkey Delphi project? I'm targeting both Windows and Mac.

I have XE2, but I suppose any version solution is fine because I will upgrade if needed.

Marcus Adams
  • 53,009
  • 9
  • 91
  • 143

3 Answers3

28

For Windows you can use the GetUserName WinAPi function, for OSX you can use the NSUserName and/or NSFullUserName methods.

Try this sample for OSX

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Macapi.CoreFoundation,
  Macapi.Foundation,
  System.SysUtils;

function NSUserName: Pointer; cdecl; external '/System/Library/Frameworks/Foundation.framework/Foundation' name _PU +'NSUserName';
function NSFullUserName: Pointer; cdecl; external '/System/Library/Frameworks/Foundation.framework/Foundation' name _PU + 'NSFullUserName';

begin
  try
    Writeln(Format('User Name      %s',[TNSString.Wrap(NSUserName).UTF8String]));
    Writeln(Format('Full User Name %s',[TNSString.Wrap(NSFullUserName).UTF8String]))
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

For Windows

{$APPTYPE CONSOLE}


uses
  Windows,
  SysUtils;

function WUserName: String;
var
  nSize: DWord;
begin
 nSize := 1024;
 SetLength(Result, nSize);
 if GetUserName(PChar(Result), nSize) then
   SetLength(Result, nSize-1)
 else
   RaiseLastOSError;
end;


begin
  try
   Writeln(WUserName);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  readln;
end.

Compiled into a single unit:

uses
  {$IFDEF MACOS}
  MacApi.CoreFoundation, MacApi.Foundation,
  {$ENDIF}
  {$IFDEF MSWINDOWS}
  Windows,
  {$ENDIF}
  System.SysUtils;

{$IFDEF MACOS}
function NSUserName: Pointer; cdecl; external '/System/Library/Frameworks/Foundation.framework/Foundation' name '_NSUserName';
{$ENDIF}

function GetUserName: String;
{$IFDEF MSWINDOWS}
var
  nSize: DWord;
{$ENDIF}
begin
  {$IFDEF MACOS}
  Result := TNSString.Wrap(NSUserName).UTF8String;
  {$ENDIF}
  {$IFDEF MSWINDOWS}
  nSize := 1024;
  SetLength(Result, nSize);
  if Windows.GetUserName(PChar(Result), nSize) then
  begin
    SetLength(Result, nSize - 1)
  end
  else
  begin
    RaiseLastOSError;
  end
  {$ENDIF}
end;
Marcus Adams
  • 53,009
  • 9
  • 91
  • 143
RRUZ
  • 134,889
  • 20
  • 356
  • 483
14

Another simpler solution is to get the computer name via the environment variable using GetEnvironmentVariable function as follows:

Result := GetEnvironmentVariable('USERNAME');

P.S.This solution is for Windows and Linux but you need to check your Delphi source code if it is supported.

mas_oz2k1
  • 2,851
  • 3
  • 34
  • 41
  • Fantastically simple (DXE3 & Win10), thanks. GetEnvironmentVariable gives so much info. +1. – Johnny Mar 13 '17 at 10:38
  • 1
    ⚠ Just keep in mind users (and apps) can easily overwrite environment variables, so it's unsafe to limit/grant user access based solely on this value. – Jeremy Apr 24 '20 at 20:57
  • GetEnvironmentVariable looks like "SYSTEM". but it returns not logged in user name. but credentials user name which you run the executable. eg. it returns admin if you "run as admin" even you are in limited user account. – Zen Of Kursat Jun 24 '20 at 17:01
  • Any application can have environment variables - and it's just a memory block so can easily be changed. It's NOT SAFE to assume that it is accurate (but I admit it's very easy to look at) – Rob Lambden Mar 17 '21 at 11:38
3

A simpler answer for windows users

function CurrentUserName:String;  
var  
  UserName: array[0..127] of Char;  
  Size:DWord;  
begin  
  Size:=SizeOf(UserName);  
  GetUserName(UserName,Size);  
  Result:=UserName;  
end;  

from edn

none
  • 4,669
  • 14
  • 62
  • 102