2011-12-09 43 views
14

我需要在Delphi中獲取域上Windows機器的完全限定域名。如何在Delphi中的窗口中獲取完全限定域名

我試着使用,但執行LookupAccountSid它給了我唯一的NetBIOS域名, 在我的情況下,它是「內聯網」,但我需要完整的「intranet.companyname.com」

什麼想法?

+0

是在companyname.com上運行的域服務器,否則即使使用正確的功能它也將爲空。 –

+1

它是一個Active Directory域嗎? –

+2

你的問題不是很清楚。所有這些信息都與**機器**相關,而不是**用戶**。 – OnTheFly

回答

8

嘗試GetUserNameEx Windows API函數。

const 
    NameUnknown   = 0; 
    NameFullyQualifiedDN = 1; 
    NameSamCompatible  = 2; 
    NameDisplay   = 3; 
    NameUniqueId   = 6; 
    NameCanonical   = 7; 
    NameUserPrincipal  = 8; 
    NameCanonicalEx  = 9; 
    NameServicePrincipal = 10; 
    NameDnsDomain   = 12; 

function GetUserNameExString(ANameFormat: DWORD): string; 
var 
    Buf: array[0..256] of Char; 
    BufSize: DWORD; 
    GetUserNameEx: function (NameFormat: DWORD; lpNameBuffer: LPSTR; 
    var nSize: ULONG): BOOL; stdcall; 
begin 
    Result := ''; 
    BufSize := SizeOf(Buf) div SizeOf(Buf[0]); 
    GetUserNameEx := GetProcAddress(GetModuleHandle('secur32.dll'), 'GetUserNameExA'); 
    if Assigned(GetUserNameEx) then 
    if GetUserNameEx(ANameFormat, Buf, BufSize) then 
     Result := Buf; 
end; 

使用例如NameDnsDomain格式,將導致www.mydomain.com\user_name,如果您登錄到「www.mydomain.com」域。


由於我現在在我們的應用程序中爲我自己的需要實現了這個功能,@ iPath的評論被放棄了。更好地使用GetComputerNameEx,並根據自己的需要指定COMPUTER_NAME_FORMAT之一。

一個Delphi實現看起來像這樣(Unicode版本):

interface 
... 
type 
    COMPUTER_NAME_FORMAT = (
    ComputerNameNetBIOS, 
    ComputerNameDnsHostname, 
    ComputerNameDnsDomain, 
    ComputerNameDnsFullyQualified, 
    ComputerNamePhysicalNetBIOS, 
    ComputerNamePhysicalDnsHostname, 
    ComputerNamePhysicalDnsDomain, 
    ComputerNamePhysicalDnsFullyQualified, 
    ComputerNameMax); 

function GetComputerNameExString(ANameFormat: COMPUTER_NAME_FORMAT): WideString; 

implementation 
... 
function GetComputerNameExW(NameType: COMPUTER_NAME_FORMAT; lpBuffer: LPWSTR; 
    var nSize: DWORD): BOOL; stdcall; external kernel32 name 'GetComputerNameExW'; 

function GetComputerNameExString(ANameFormat: COMPUTER_NAME_FORMAT): WideString; 
var 
    nSize: DWORD; 
begin 
    nSize := 1024; 
    SetLength(Result, nSize); 
    if GetComputerNameExW(ANameFormat, PWideChar(Result), nSize) then 
    SetLength(Result, nSize) 
    else 
    Result := ''; 
end; 
+0

您能否建議需要將什麼參數傳遞給此API? –

+0

@David,看我的更新 – kobik

+0

應該使用哪種名字格式? –

1

NetGetJoinInformation應該可以正常工作。

MSDN:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa370423(v=vs.85).aspx

例子:

type 
    PWKSTA_INFO_100 = ^WKSTA_INFO_100; 

    WKSTA_INFO_100 = packed record 
    wki100_platform_id: DWord; 
    wki100_computername: PWChar; 
    wki100_langroup: PWChar; 
    wki100_ver_major: DWord; 
    wki100_ver_minor: DWord; 
    end; 

    TNetSetupJoinStatus = 
    (
    NetSetupUnknownStatus, 
    NetSetupUnjoined, 
    NetSetupWorkgroupName, 
    NetSetupDomainName 
); 

    TNetApiBufferFreeFunction = function(ABuffer: Pointer): DWORD; stdcall; 
    TNetWkstaGetInfoFunction = function(const AServername: PWChar; const ALevel: DWord; const ABufptr: Pointer): DWORD; stdcall; 
    TNetGetJoinInformationFunction = function(const AServerName: PWChar; out ANameBuffer: PWChar; out ABufferType: TNetSetupJoinStatus): DWORD; stdcall; 

const 
    NERR_SUCCESS = 0; 

function GetLocalComputerDomainName: string; 
var 
    NetApiBuffer: Pointer; 
    NetApi: THandle; 
    NetApiBufferFree: TNetApiBufferFreeFunction; 
    NetWkstaGetInfo: TNetWkstaGetInfoFunction; 
    NetGetJoinInformation: TNetGetJoinInformationFunction; 
    NetSetupJoinStatus: TNetSetupJoinStatus; 
    NameBuffer: PWideChar; 
begin 
    Result := ''; 
    NetApi := LoadLibrary('netapi32.dll'); 
    if NetApi <> 0 then 
    begin 
    NetApiBufferFree  := TNetApiBufferFreeFunction( GetProcAddress(NetApi, 'NetApiBufferFree')); 
    NetGetJoinInformation := TNetGetJoinInformationFunction(GetProcAddress(NetApi, 'NetGetJoinInformation')); 
    NetWkstaGetInfo  := TNetWkstaGetInfoFunction(  GetProcAddress(NetApi, 'NetWkstaGetInfo')); 
    if @NetApiBufferFree <> nil then 
    begin 
     if @NetSetupJoinStatus <> nil then 
     begin 
     if NetGetJoinInformation(nil, NameBuffer, NetSetupJoinStatus) = NERR_SUCCESS then 
     begin 
      if NetSetupJoinStatus = NetSetupDomainName then 
      begin 
      Result := NameBuffer; 
      end; 
      NetApiBufferFree(NameBuffer); 
     end; 
     end; 
    end; 
    FreeLibrary(NetApi); 
    end; 
end; 
+0

它返回的可能取決於域網絡的設置方式。對不起,我不知道詳細信息,但我只在工作時使用'NetGetJoinInformation'獲取一個簡單的域名。 –

+0

如果域名不以'.companyname.com'結尾,則爲真。在這種情況下,IP地址上的反向DNS查詢可能會得到FQDN,這也可能是OP所需的。 –

+2

不幸的是你的代碼只返回我的域名的「內部網」部分。至少在我的領域。 – Gilmor

1

我嘗試了所有的方法,但都沒有成功。最後,我決定只是抓住環境變量。

uses jclSysInfo; 

function GetDomain:string; 
begin 
    result:=GetEnvironmentVariable('USERDNSDOMAIN'); 
end; 

在Server 2008 R2上測試 - 工作正常。返回「server.home.lan」。 在Windows 7非域連接的PC上產生一個空字符串。

+0

還需要檢查InternetGetConnectedState,因爲如果您失去連接,USERDNSDOMAIN不會被清除。您可以通過拔下網線來驗證有線網絡。 –

相關問題