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

Kob*_*alt 4 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;
Run Code Online (Sandbox Code Playgroud)

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

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

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

谢谢.

Dav*_*nan 12

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

SetLength(sUserName, dwUserNameLen);
Run Code Online (Sandbox Code Playgroud)

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

所以你修复它像这样:

SetLength(sUserName, dwUserNameLen-1);
Run Code Online (Sandbox Code Playgroud)

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

if not GetUserName(PChar(sUserName), dwUserNameLen) then
  RaiseLastOSError;
Run Code Online (Sandbox Code Playgroud)

或者一个比较危险的变种:

Win32Check(GetUserName(PChar(sUserName), dwUserNameLen));
Run Code Online (Sandbox Code Playgroud)

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

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

  • "最后一点"部分+1,这是答案中最重要的部分. (3认同)