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

问题描述 投票:0回答:3
在那里,我在Windows 8中使用XE3的Delphi FM2。

即时消息是我希望用户按下按钮,然后导航到AppData Ex中的子文件夹。 C:\ Users \ Kobus \ AppData \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 \'

thanks.

问题是

dwUserNameLen

包含字符串的长度,包括尾随的零终结器。所以当你这样做时:

SetLength(sUserName, dwUserNameLen);
delphi firemonkey
3个回答
12
投票
这将导致设置为

sUserName

。在某个时候,您然后将其传递到Windows API对话框函数,该函数将字符串视为null终止的字符串,并在流浪null-terminator处截断字符串。

因此,您这样解决了:

'Kobus#0'

注意,如果呼叫失败,您还应该检查

SetLength(sUserName, dwUserNameLen-1);
的返回值:
GetUserName

或一个相当清晰的变体:

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

最后一点。这是持有漫游应用数据文件夹的错误方法。首先,您正在假设各种实施详细信息。您的方法将在使用不同命名模式的Windows的旧版本上失败。或Windows的一些未来版本。或以不同方式配置的当前版本。

正确的方法是询问系统漫游应用数据文件夹在哪里。使用
Win32Check(GetUserName(PChar(sUserName), dwUserNameLen));

(适用于旧的Windows版本)或
CSIDL_APPDATA
(对于现代Windows版本)。

我认为您的问题是Xy问题之一。

您想阅读的完整道路
FOLDERID_RoamingAppData

的实际问题

您在思考如何阅读当前

%AppData%\.minecraft\saves\

Csidl

1
投票
ShgetFolderPath

Username

update

检查

单元中的

gethomepath功能。 将与多平台相同的结果。 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

这种小方法对我来说很好

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


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

tosets

function GetCurrentUserName: string; var Size: DWORD; begin Size := 253; SetLength(Result, Size); Win32Check(GetUserName(PChar(Result), Size)); // Raise exception if GetUserName fails SetLength(Result, Size - 1); end;
to当前用户的名称,避免了复杂性。
    

1
投票
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.