简体   繁体   English

如何在Delphi Win64中获取当前用户的全名

[英]How to get Full Name of current user in Delphi Win64

I've done a fair amount of searching and have found some useful tips right here on Stackoverflow to get the Username and Computer name - and I've even found some code posted by Norrit on Delphipages doing exactly what I need it to do - except that when running it under a Win64 Target Platform, obtaining the Full Name doesn't work - it returns an empty string. 我已经做了很多搜索,并且在Stackoverflow上找到了一些有用的技巧来获取用户名和计算机名-甚至我发现 Norrit在Delphipages上发布的代码完全可以满足我的要求-除了在Win64目标平台上运行它时,获取全名不起作用-它返回一个空字符串。 It returns the full name fine when running a Win32 build. 它在运行Win32版本时返回全名。

The GetCurrentUser and GetDomainServerName functions work in both Win32 and Win64. GetCurrentUser和GetDomainServerName函数可在Win32和Win64中使用。

Doing Google searches for "delphi netusergetinfo" brings up a lot of results which are more than 10 years old - even before Delphi had Win64. 谷歌搜索“delphi netusergetinfo”会带来很多超过10年的结果 - 甚至在Delphi使用Win64之前。 It also brings up an Experts-Exchange answer which links to some lanman example code which 404's on me, so I'm a bit stuck there. 它还提出了一个专家交流答案,链接到一些我在上面的一些lanman示例代码,所以我有点卡在那里。

Does anybody know what changes I have to make to get GetDomainFullName to work under Win64 - or does anybody have alternate code I can use to obtain the Full Name of the currently logged on user? 有没有人知道我必须做什么改变才能让GetDomainFullName在Win64下运行 - 或者是否有人有替代代码我可以用来获取当前登录用户的全名?

Full code shown below in case of link rot. 链接腐烂时,如下所示的完整代码。

unit NetAPI32;

interface

uses
  Windows, SysUtils;

  function GetCurrentUser(): String;
  function GetDomainServerName(): String;
  function GetDomainFullName(ServerName, UserName: String): String;

implementation

  function NetUserGetInfo(ServerName, UserName: PWideChar; Level: DWORD; var Buffer: Pointer): DWORD; stdcall; external 'netapi32.dll' name 'NetUserGetInfo';
  function NetApiBufferFree(Buffer: pointer): DWORD; stdcall; external 'netapi32.dll' name 'NetApiBufferFree';
  function NetWkstaUserGetInfo(ServerName: PWideChar; Level: DWORD; var Buffer: Pointer): Longint; stdcall; external 'netapi32.dll' name 'NetWkstaUserGetInfo';

type
  TUserInfo1 = packed record
    UserName: PWideChar;
    DomainName : PWideChar;
    OtherDomainNames: PWideChar;
    ServerName: PWideChar;
  end;
  PUserInfo1 = ^TUserInfo1;

  TUserInfo2 = packed record
    Name: PWideChar;
    Password: PWideChar;
    PasswordAge: DWORD;
    Priv: DWORD;
    HomeDir: PWideChar;
    Comment: PWideChar;
    Flags: DWORD;
    ScriptPath: PWideChar;
    AuthorFlags: DWORD;
    FullName: PWideChar;
    UserComment: PWideChar;
    Params: PWideChar;
    WorkStations: PWideChar;
    LastLogon: DWORD;
    LastLogoff: DWORD;
    AccountExpires: DWORD;
    MaxStorage: DWORD;
    UnitsPerWeek: DWORD;
    LogonHours: DWORD;
    BadPasswordCount: DWORD;
    LogonCount: DWORD;
    Server: PWideChar;
    CountryCode: DWORD;
    Codepage: DWORD;
  end;
  PUserInfo2 = ^TUserInfo2;

function GetCurrentUser(): String;
var
  username: String;
  size: DWORD;
begin
  size := 255;
  SetLength(username, size) ;
  if GetUserName(PChar(username), size) then
    Result := Copy(username, 1, size - 1)
  else
    Result := '';
end;

function GetDomainServerName(): String;
var
  PUI1: PUserInfo1;
begin
  Result := '';
  if NetWkstaUserGetInfo(nil, 1, Pointer(PUI1)) = 0 then
  begin
    try
      Result := WideCharToString(PUI1^.ServerName);
    finally
      NetApiBufferFree(PUI1);
    end;
  end;
end;

function GetDomainFullName(ServerName, UserName: String): String;
var
  PUI2: PUserInfo2;
begin
  Result := '';
  if NetUserGetInfo(PWideChar(WideString(ServerName)), PWideChar(WideString(UserName)), 2, Pointer(PUI2)) = 0 then
    try
      Result := WideString(PUI2^.FullName);
    finally
      NetApiBufferFree(PUI2);
    end;
end;

end.

Example of how to use: 如何使用示例:

ShowMessage(GetDomainFullName(GetDomainServerName(), GetCurrentUser()));

Delphi XE6 running on Windows 2012 R2 在Windows 2012 R2上运行的Delphi XE6

The use of packed is wrong, and has always been wrong. 使用packed是错误的,并且始终是错误的。 You just got away with it because it so happened that the layout on 32 bit is the same packed as aligned. 你刚刚离开它,因为它发生了32位的布局与对齐的相同。

Remove the packed modifier from the struct declarations and your code will work. 从struct声明中删除packed修饰符,您的代码将起作用。

Since you've moved to Unicode Delphi, you can stop using WideString now. 由于您已移至Unicode Delphi,因此现在可以停止使用WideString

function GetDomainFullName(const ServerName, UserName: string): string;
var
  PUI2: PUserInfo2;
begin
  if NetUserGetInfo(PChar(ServerName), PChar(UserName), 2, Pointer(PUI2)) = 0 then
    try
      Result := PUI2^.FullName;
    finally
      NetApiBufferFree(PUI2);
    end
  else
    Result := '';
end;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM