私のアプリは、Active Directory ドメインに参加しているコンピューターで実行されています。WinAPI メソッドを使用してそのドメインの DNS 名を取得する方法はありますか? DNS サーバーやドメイン コントローラーが利用できない場合でも機能するものが必要です。
現在、私が見つけることができる唯一の方法は、Win32_ComputerSystem WMI クラスの Domain プロパティを使用することです。
using System.Management;
public class WMIUtility
{
public static ManagementScope GetDefaultScope(string computerName)
{
ConnectionOptions connectionOptions = new ConnectionOptions();
connectionOptions.Authentication = AuthenticationLevel.PacketPrivacy;
connectionOptions.Impersonation = ImpersonationLevel.Impersonate;
string path = string.Format("\\\\{0}\\root\\cimv2", computerName);
return new ManagementScope(path, connectionOptions);
}
public static ManagementObject GetComputerSystem(string computerName)
{
string path = string.Format("Win32_ComputerSystem.Name='{0}'", computerName);
return new ManagementObject(
GetDefaultScope(computerName),
new ManagementPath(path),
new ObjectGetOptions()
);
}
public static string GetDNSDomainName(string computerName)
{
using (ManagementObject computerSystem = GetComputerSystem(computerName))
{
object isInDomain = computerSystem.Properties["PartOfDomain"].Value;
if (isInDomain == null) return null;
if(!(bool)isInDomain) return null;
return computerSystem.Properties["Domain"].Value.ToString();
}
}
}
WinAPI で見つけることができる唯一のものは、NetBIOS ドメイン名を返す NetGetJoinInformation メソッドです。
using System.Runtime.InteropServices;
public class PInvoke
{
public const int NERR_SUCCESS = 0;
public enum NETSETUP_JOIN_STATUS
{
NetSetupUnknownStatus = 0,
NetSetupUnjoined,
NetSetupWorkgroupName,
NetSetupDomainName
}
[DllImport("netapi32.dll", CharSet = CharSet.Unicode)]
protected static extern int NetGetJoinInformation(string lpServer, out IntPtr lpNameBuffer, out NETSETUP_JOIN_STATUS BufferType);
[DllImport("netapi32.dll", SetLastError = true)]
protected static extern int NetApiBufferFree(IntPtr Buffer);
public static NETSETUP_JOIN_STATUS GetComputerJoinInfo(string computerName, out string name)
{
IntPtr pBuffer;
NETSETUP_JOIN_STATUS type;
int lastError = NetGetJoinInformation(computerName, out pBuffer, out type);
if(lastError != NERR_SUCCESS)
{
throw new System.ComponentModel.Win32Exception(lastError);
}
try
{
if(pBuffer == IntPtr.Zero)
{
name = null;
}
else
{
switch(type)
{
case NETSETUP_JOIN_STATUS.NetSetupUnknownStatus:
case NETSETUP_JOIN_STATUS.NetSetupUnjoined:
{
name = null;
break;
}
default:
{
name = Marshal.PtrToStringUni(pBuffer);
break;
}
}
}
return type;
}
finally
{
if(pBuffer != IntPtr.Zero)
{
NetApiBufferFree(pBuffer);
}
}
}
}