Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the name of the current user in delphi?

Hi there i am using delphi FM2 with XE3 in windows 8.

The problem im having is that i want the user to press a button and then navigate to a subfolder located in appdata ex. C:\Users\Kobus\AppData\Roaming.minecraft

Everybody has a diferant username so this wont work.

So i use this code to get the username:

function GetCurrentUserName : string;
const
  cnMaxUserNameLen = 254;
var
  sUserName     : string;
  dwUserNameLen : DWord;
begin
  dwUserNameLen := cnMaxUserNameLen-1;
  SetLength( sUserName, cnMaxUserNameLen );
  GetUserName(PChar( sUserName ),dwUserNameLen );
  SetLength( sUserName, dwUserNameLen );
  Result := sUserName;
end;

username := GetCurrentUserName;

Then i say ShowMessage('C:\Users\'+username+'\AppData\Roaming\.minecraft\saves\'); to check the output.

And the output i get is : 'C:\Users\Kobus' for some reason the rest of the path name is lost.

What i need to be displayed is : 'C:\Users\'Kobus'\AppData\Roaming.minecraft\saves\'

Thanks.

like image 886
Kobus Vdwalt Avatar asked Dec 20 '22 08:12

Kobus Vdwalt


1 Answers

The problem is that dwUserNameLen contains the length of the string, including the trailing zero terminator. So when you do:

SetLength(sUserName, dwUserNameLen);

this results in sUserName being set to 'Kobus#0'. At some point you then pass this to a Windows API dialog function that treats the string as a null-terminated string, and truncates the string at the stray null-terminator.

So you fix it like this:

SetLength(sUserName, dwUserNameLen-1);

Note that you should also check the return value of GetUserName in case that call fails:

if not GetUserName(PChar(sUserName), dwUserNameLen) then
  RaiseLastOSError;

or a rather crisper variant:

Win32Check(GetUserName(PChar(sUserName), dwUserNameLen));

One final point. This is the wrong way to get hold of the roaming app data folder. For a start you are assuming all sorts of implementation details. Your approach will fail on older versions of Windows which use different naming patterns. Or some future version of Windows. Or the current versions that have been configured in a different way.

The right way to do this is to ask the system where the roaming app data folder is. Do that using CSIDL_APPDATA (for older Windows versions), or FOLDERID_RoamingAppData (for modern Windows versions).

like image 85
David Heffernan Avatar answered Dec 24 '22 02:12

David Heffernan