2014-09-03 97 views
2

我已經做了大量的搜索並發現了一些有用的提示right here on Stackoverflow以獲取用戶名和計算機名 - 我甚至還發布了found some code由Delrit在Delphipages上做正是我需要它做的 - 除了在Win64目標平臺下運行它時,獲取全名不起作用 - 它會返回一個空字符串。它在運行Win32構建時返回完整的名稱。如何在Delphi Win64中獲取當前用戶的全名

GetCurrentUser和GetDomainServerName函數同時在Win32和Win64中工作。

做谷歌搜索「delphi netusergetinfo」帶來了很多超過10年的結果 - 甚至在Delphi有Win64之前。它也提出了一個專家交換的答案,它鏈接到404上的一些lanman示例代碼,所以我有點卡在那裏。

是否有人知道我必須做出什麼樣的修改才能使GetDomainFullName在Win64下工作 - 或者是否有人可以使用替代代碼來獲取當前登錄用戶的全名?

完整代碼如下所示,以防鏈接腐爛。

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. 

如何使用示例:在Windows 2012上運行

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

德爾福XE6 R2

+1

使用[System.SysUtils.Win32Check(http://docwiki.embarcadero.com/Libraries/XE6/en/System.SysUtils.Win32Check),以獲得爲什麼API調用失敗 – 2014-09-03 20:31:23

回答

7

使用的packed是錯誤的,而且一直錯了。你剛剛離開它,因爲它碰巧發生在32位的佈局與對齊相同。

從struct聲明中刪除packed修飾符,您的代碼將工作。

由於您已經轉移到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; 
+0

事實上,去除原因「包裝」從我的單位固定的問題:)感謝親切。 – KeyszerS 2014-09-03 20:33:12