4 Stimmen

WinAPI-Entsprechung von Win32_ComputerSystem.Domain

Meine Anwendung läuft auf einem Computer, der mit einer Active Directory-Domäne verbunden ist. Gibt es eine Möglichkeit, den DNS-Namen dieser Domäne mit WinAPI-Methoden abzurufen? Ich möchte etwas, das auch dann funktioniert, wenn keine DNS-Server oder Domänencontroller verfügbar sind.

Im Moment ist die einzige Möglichkeit, die ich finden kann, die Domäneneigenschaft der WMI-Klasse Win32_ComputerSystem:

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();
        }
    }
}

Das einzige, was ich in WinAPI finden kann, ist die Methode NetGetJoinInformation, die den NetBIOS-Domänennamen zurückgibt:

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

3voto

0xC0000022L Punkte 19207

Ich denke, was Sie suchen, ist GetComputerNameEx mit ComputerNameDnsDomain als ersten Parameter. Aber es ist möglich, dass Sie einen der anderen Typen dort haben wollen. Trotzdem, GetComputerNameEx ist die Funktion, nach der Sie suchen, so wie ich die Frage verstehe.

PInvoke-Details hier .

Sie sprechen in Ihrem Kommentar einen berechtigten Punkt an, der in diesem Fall sicher LsaQueryInformationPolicy mit PolicyDnsDomainInformation ist möglicherweise der bessere Weg, um den DNS-Namen der Domäne zu erhalten, in der der Computer Mitglied ist.

Aber das ist ein Sonderfall, und in Ihrer Frage war von einem solchen Sonderfall nicht die Rede. Dies sollte nur dann der Fall sein, wenn das primäre DNS-Suffix festgelegt wurde und sich von dem DNS-Domänennamen unterscheidet, zu dem der Rechner gehört. Für alle praktischen Zwecke GetComputerNameEx wird genau das tun, was Sie wollen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X