嗨,我在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版本).