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

非 Y 不嫁゛ 提交于 2020-01-14 10:42:11

问题


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.


回答1:


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).




回答2:


I didn't need to dig too long to find a snippet :). So what I use in my own app, after summarising the hints, becomes:

//=================================================================
procedure TMainF1.UserTestClick(Sender: TObject);
const
  cnMaxUserNameLen = 254;
var
  sUserName     : string;
  dwUserNameLen : DWord;
begin
  dwUserNameLen := cnMaxUserNameLen-1;
  SetLength( sUserName, cnMaxUserNameLen );
  Win32Check(GetUserName( PChar(sUserName), dwUserNameLen ));
  sUserName := PChar( sUserName );
  label_user.Caption := UpperCase(sUserName);
end;

//== works well with D7



回答3:


i Think your question is one of the XY Problems

Your actual problem that you want to read the full path of %AppData%\.minecraft\saves\

And you thinking in how to read the current Username

Look at CSIDL and SHGetFolderPath

function GetShellFolder(CSIDLFolder : integer) : string;
begin
  SetLength(Result, MAX_PATH);
  SHGetSpecialFolderPath(0, PChar(Result), CSIDLFolder, false);
  SetLength(Result, StrLen(PChar(Result)));
  if (Result <> '') then
    Result  := IncludeTrailingBackslash(Result);
end;

....

//Usage
ShowMessage(GetShellFolder(CSIDL_APPDATA)+'.minecraft\saves');

UPDATE

Alternative

Check the GetHomePath function in System.IOUtils unit.

Will do the same result that you want for multi platforms.

uses System.IOUtils;

procedure TForm17.btn1Click(Sender: TObject);
begin
    ShowMessage(TPath.GetHomePath() + TPath.DirectorySeparatorChar + '.minecraft\saves');
end;



回答4:


username := GetEnvironmentVariable('username');

sets username to the current user's name, obviating the complexity.



来源:https://stackoverflow.com/questions/15555527/how-to-get-the-name-of-the-current-user-in-delphi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!