即时消息是我希望用户按下按钮,然后导航到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);
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
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
这种小方法对我来说很好
//=================================================================
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当前用户的名称,避免了复杂性。