如何在delphi中获取当前用户的名称?

时间:2013-03-21 18:38:07

标签: delphi firemonkey

您好我在Windows 8中使用delphi FM2和XE3。

我遇到的问题是我希望用户按下按钮,然后导航到位于appdata ex中的子文件夹。 C:\ Users \用户Kobus \应用程序数据\ Roaming.minecraft

每个人都有一个不同的用户名,所以这不会起作用。

所以我使用这段代码来获取用户名:

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;

然后我说ShowMessage('C:\Users\'+username+'\AppData\Roaming\.minecraft\saves\');检查输出。

我得到的输出是:'C:\ Users \ Kobus'由于某种原因导致路径名的其余部分丢失。

我需要显示的是:'C:\ Users \'Kobus'\ AppData \ Roaming.minecraft \ saves \'

感谢。

4 个答案:

答案 0 :(得分:12)

问题是dwUserNameLen包含字符串的长度,包括尾随零终止符。所以当你这样做时:

SetLength(sUserName, dwUserNameLen);

这导致sUserName设置为'Kobus#0'。在某些时候,您可以将其传递给Windows API对话框函数,该函数将字符串视为以null结尾的字符串,并在stray null-terminator处截断字符串。

所以你这样修理它:

SetLength(sUserName, dwUserNameLen-1);

请注意,如果调用失败,您还应检查GetUserName的返回值:

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

或一个相当保守的变体:

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

最后一点。这是获取漫游应用程序数据文件夹的错误方法。首先,您要假设各种实现细节。在使用不同命名模式的旧版Windows上,您的方法将失败。或者是Windows的未来版本。或者以不同方式配置的当前版本。

执行此操作的正确方法是询问系统漫游应用程序数据文件夹的位置。使用CSIDL_APPDATA(适用于较旧的Windows版本)或FOLDERID_RoamingAppData(适用于现代Windows版本)执行此操作。

答案 1 :(得分:1)

我不需要花太长时间才能找到一个片段:)。 因此,在总结提示后,我在自己的应用程序中使用的内容变为:

//=================================================================
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

答案 2 :(得分:0)

我认为您的问题是XY Problems

之一

您想要阅读%AppData%\.minecraft\saves\

的完整路径的实际问题

您在考虑如何阅读当前的Username

查看CSIDLSHGetFolderPath

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');

<强>更新

替代

检查System.IOUtils单元中的GetHomePath功能。

将为多平台做同样的结果。

uses System.IOUtils;

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

答案 3 :(得分:-2)

username := GetEnvironmentVariable('username');

username设置为当前用户的名称,从而避免了复杂性。