如何在 Delphi 中在 Windows 上获取完全限定的域名
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8446940/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get fully qualified domain name on Windows in Delphi
提问by Gilmor
I need to get a fully qualified domain name for a Windows machine on a domain in Delphi.
我需要在 Delphi 的域上为 Windows 机器获取一个完全限定的域名。
I've tried to use LookupAccountSid
but it gives me only the netbios domain name,
in my case it is "intranet" but I need the full "intranet.companyname.com"
我尝试使用LookupAccountSid
但它只给了我 netbios 域名,在我的情况下它是“intranet”但我需要完整的“intranet.companyname.com”
Any Ideas?
有任何想法吗?
采纳答案by kobik
Try the GetUserNameEx
Windows API function.
尝试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;
using the NameDnsDomain
format for example, will result www.mydomain.com\user_name
if you are logged into "www.mydomain.com" domain.
NameDnsDomain
例如,www.mydomain.com\user_name
如果您登录到“www.mydomain.com”域,将使用该格式。
Since I now implemented this for my own needs in our application, @iPath's comment was quit right. better use GetComputerNameEx
, and specify one of the COMPUTER_NAME_FORMAT
for your own needs.
由于我现在在我们的应用程序中根据自己的需要实现了这一点,@iPath 的评论是正确的。更好地使用GetComputerNameEx
,并COMPUTER_NAME_FORMAT
根据您自己的需要指定其中之一。
A Delphi implementation would look like this (Unicode version):
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;
回答by Steve Rymer
I tried all of the above, but without success. In the end, I settled for simply grabbing the environment variable.
我尝试了上述所有方法,但没有成功。最后,我决定简单地获取环境变量。
uses jclSysInfo;
function GetDomain:string;
begin
result:=GetEnvironmentVariable('USERDNSDOMAIN');
end;
Tested on Server 2008 R2 - works fine. Returns "server.home.lan". Results in an empty string on a Windows 7 non-domain connected PC.
在 Server 2008 R2 上测试 - 工作正常。返回“server.home.lan”。在 Windows 7 非域连接 PC 上产生空字符串。
回答by Jens Mühlenhoff
NetGetJoinInformation
should work fine.
NetGetJoinInformation
应该工作正常。
MSDN:
微软:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa370423(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa370423(v=vs.85).aspx
Example:
例子:
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;
回答by Egbert Nierop
The only correct api to use is DsGetDcName. Because NetGetJoinInformation is still from the 'lanmanager age' so, the domain is LM compliant.
唯一正确使用的 api 是 DsGetDcName。因为 NetGetJoinInformation 仍然来自“lanmanager 时代”,所以该域是 LM 兼容的。
The code here is C, but you are smart enough to do the same in Delphi :)
这里的代码是 C,但你足够聪明,可以在 Delphi 中做同样的事情:)
PDOMAIN_CONTROLLER_INFOW pdomInfo ;
auto result1 = ::DsGetDcNameW(nullptr, nullptr, nullptr, nullptr, DS_DIRECTORY_SERVICE_PREFERRED | DS_RETURN_DNS_NAME, &pdomInfo);
if (result1 == ERROR_SUCCESS) {
auto retVal = SysAllocString(pdomInfo->DomainName);
::NetApiBufferFree(pdomInfo);
}