我一直在使用Lazarus 1.6.4和FPC 3.0.2编写一些代码,以便在Windows中获取用户名,在Linux中获取用户。为此,我使用了SysUtils.GetEnvironmentVariable函数。在Linux中,它工作得很完美,但在Windows中,它会返回一些看起来像是以错误编码打开的UTF8字符串的损坏内容。在Windows中,我的用户名包含西里尔字母,所以GetEnvironmentVariable返回的不是实际名称,而是????????,但它应该是Пользователь。下面是我的代码:
function GetUserName: string;
{$IFDEF MSWINDOWS}
const
envVar = 'USERNAME';
{$ENDIF}
{$IFDEF UNIX}
envVar = 'USER';
{$ENDIF}
begin
Result := SysUtils.GetEnvironmentVariable(envVar);
{$IFDEF MSWINDOWS}
{ TODO : BUG: Does not work correct for non-latin strings }
Result := LazUTF8.UTF8ToWinCP(Result)
{$ENDIF}
end;并且当其中包含非后缀符号时,它会返回损坏的字符串。
如何在Windows操作系统中GetEnvironmentVariable in正确的编码?
发布于 2017-12-04 23:29:56
对于windows上的unicodestring,3.0+获取环境变量中的Afaik是重载的,并且使用了-W变量。
var res,tag : unicodestring;
begin
tag:='HOME';
res:=getenvironmentvariable(tag);
end;只是
getenvironmentstring (unicodestring('whatever'));也可能有效,但请确保将utf8设置为默认编码,或者将结果分配给unicodestring。
发布于 2017-12-01 14:59:31
经过一天的跑步,我找到了适合我的解决方案。您应该使用SysUtils.GetEnvironmentVariable的Unicode版本,并将结果转换为Windows当前代码页。下面的代码如下:
uses
{$IFDEF MSWINDOWS}
LazUTF8
{$ENDIF}
;
function GetUserName: string;
const
envVar: UnicodeString =
{$IFDEF MSWINDOWS}
'USERNAME'
{$ENDIF}
{$IFDEF UNIX}
'USER'
{$ENDIF};
begin
// USE Unicode String Version only!
Result := SysUtils.GetEnvironmentVariable(envVar);
{$IFDEF MSWINDOWS}
Result := LazUTF8.UTF8ToWinCP(Result)
{$ENDIF}
end; 正如大卫在评论中提到的那样,更新01.12.2017我的解决方案依赖于ENV。在讨论中,我发现了更可靠的解决方案here。代码如下:
function GetCurrentUserName: String;
{$IFDEF WINDOWS}
const
MaxLen = 256;
var
Len: DWORD;
WS: WideString;
Res: windows.BOOL;
{$ENDIF}
begin
Result := '';
{$IFDEF UNIX}
{$IF (DEFINED(LINUX)) OR (DEFINED(FREEBSD))}
Result := SysToUtf8(GetUserName(fpgetuid)); //GetUsername in unit Users, fpgetuid in unit BaseUnix
{$ELSE Linux/BSD}
Result := GetEnvironmentVariableUtf8('USER');
{$ENDIF UNIX}
{$ELSE}
{$IFDEF WINDOWS}
Len := MaxLen;
{$IFnDEF WINCE}
if Win32MajorVersion <= 4 then
begin
SetLength(Result,MaxLen);
Res := Windows.GetuserName(@Result[1], Len);
//writeln('GetUserNameA = ',Res);
if Res then
begin
SetLength(Result,Len-1);
Result := SysToUtf8(Result);
end
else SetLength(Result,0);
end
else
{$ENDIF NOT WINCE}
begin
SetLength(WS, MaxLen-1);
Res := Windows.GetUserNameW(@WS[1], Len);
//writeln('GetUserNameW = ',Res);
if Res then
begin
SetLength(WS, Len - 1);
Result := Utf16ToUtf8(WS);
end
else SetLength(Result,0);
end;
{$ENDIF WINDOWS}
{$ENDIF UNIX}
end;https://stackoverflow.com/questions/47588153
复制相似问题