2012-06-13 3 views
2

Мое приложение работает на компьютере, который подключен к домену Active Directory. Есть ли способ получить DNS-имя этого домена с помощью методов WinAPI? Я хочу что-то, что будет работать, даже если нет DNS-серверов или контроллеров домена.WinAPI эквивалент Win32_ComputerSystem.Domain

Прямо сейчас, единственный способ, которым я могу найти через свойство домена класса Win32_ComputerSystem WMI:

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 является метод NetGetJoinInformation, который возвращает имя NetBIOS домена :

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); 
      } 
     } 
    } 
} 
+0

Таким образом, вы не хотите разрешать имя, но скорее получите имя домена, членом которого является компьютер, не так ли? То есть суффикс, который добавляется к имени DNS, когда эта машина выполняет динамическую регистрацию DNS? – 0xC0000022L

+0

@STATUS_ACCESS_DENIED Правильно, домен, членом которого является компьютер. Я отредактировал вопрос, чтобы попытаться сделать это более ясным. –

ответ

2

Я думаю, что вы ищете, GetComputerNameEx с ComputerNameDnsDomain в качестве первого параметра. Но, возможно, вам нужен один из других типов. Тем не менее, GetComputerNameEx - это функция, которую вы ищете, как я понимаю вопрос.

PInvoke подробности here.

Вы поднимаете справедливую точку в своем комментарии, так что, в этом случае LsaQueryInformationPolicy с PolicyDnsDomainInformation может быть лучшим способом получить DNS-имя домена, членом которого является компьютер.

Но это особый случай, и ваш вопрос не упоминал о таких особых случаях. Это должно происходить только в том случае, если основной DNS-суффикс был установлен и отличается от имени домена DNS, членом которого является устройство. Для всех практических целей GetComputerNameEx будет делать именно то, что вы хотите.

+0

В разделе примечаний для GetComputerNameEx говорится: «Если вы работаете со средами, использующими разные макеты DNS, где полное доменное имя компьютера не совпадает с полным доменным именем его домена, вместо этого используйте LsaQueryInformationPolicy». Я думаю, что LsaQueryInformationPolicy - это то, что я ищу. –

+0

Достаточно честный, по крайней мере, я добрался до вас. Имейте в виду: никто, кроме вас, не может узнать эти детали из вопроса, как вы его дали :) – 0xC0000022L

+0

Мой вопрос может быть не таким ясным, как это могло бы быть, но я думаю, что попросил эквивалент Win32_ComputerSystem.Domain дал очень ясное описание о том, что я просил. Согласно цитате, которую я дал, мне казалось, что GetComputerNameEx может вернуть что-то другое, чем Win32_ComputerSystem.Domain. –

Смежные вопросы