Составление запроса в WqlEventQuery для более чем одного сетевого адаптера завершается неудачно в C#

Я пытаюсь обнаружить изменения DNS для 2 сетевых адаптеров.
Я использую C# .net 4.0 на win 7 64-битной машине.
Код для прослушивания win ключей реестра сетевых адаптеров (внутри RegisterToDNSChanges):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.NetworkInformation;
using System.Management;
using System.Threading;

namespace CheckDNS
{
    class NetworkAdapterInfo
    {
        private Dictionary<NetworkInterface, IPAddress> m_dDNSinfo = new Dictionary<NetworkInterface, IPAddress>();
        private ManagementEventWatcher m_watcher = null;

        private NetworkAdapterInfo() 
        {
            getDNSAddresses();
            displayDNSInfo();
        }

        private static NetworkAdapterInfo _instance;

        /*
         * Instance creator (geter)
         * */
        public static NetworkAdapterInfo Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new NetworkAdapterInfo();
                }
                return _instance;
            }
        }

        /*
         * Gets all DNS addresses for all Network cards
         * Optionally changes all DNS addresses to a specified one
         * */
        private void getDNSAddresses()
        {
            NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
            foreach (NetworkInterface adapter in adapters)
            {
                IPInterfaceProperties adapterProperties = adapter.GetIPProperties();
                IPAddressCollection dnsServers = adapterProperties.DnsAddresses;
                if (dnsServers.Count > 0)
                {
                    foreach (IPAddress dns in dnsServers)
                    {
                        if (IsIPv4(dns.ToString()))
                        {
                            m_dDNSinfo.Add(adapter, dns);
                        }
                    }
                }
            }
        }

        /*
         * Displays the Network adapter DNS servers
         * */
        public void displayDNSInfo()
        {
            foreach (KeyValuePair<NetworkInterface, IPAddress> pair in m_dDNSinfo)
            {
                Console.WriteLine("Adapter: {0}\n DNS Server : {1}", pair.Key.Description, pair.Value.ToString());
            }
        }

        /*
         * Check to see if the ip is a valid one
         * param value[in]: ip string
         * @return true if it's a valid ip address
         * */
        public bool IsIPv4(string value)
        {
            var quads = value.Split('.');

            // if we do not have 4 quads, return false
            if (!(quads.Length == 4)) return false;

            // for each quad
            foreach (var quad in quads)
            {
                int q;
                // if parse fails 
                // or length of parsed int != length of quad string (i.e.; '1' vs '001')
                // or parsed int < 0
                // or parsed int > 255
                // return false
                if (!Int32.TryParse(quad, out q)
                    || !q.ToString().Length.Equals(quad.Length)
                    || q < 0
                    || q > 255) { return false; }

            }

            return true;
        }

        /*
         * Used to verify if new DNS addresses found besides the ones already stored
         * Optionally changes the DNS addreses
         * */
        private void checkIFDNSChanged()
        {
            NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
            foreach (NetworkInterface adapter in adapters)
            {
                IPInterfaceProperties adapterProperties = adapter.GetIPProperties();
                IPAddressCollection dnsServers = adapterProperties.DnsAddresses;
                if (dnsServers.Count > 0)
                {
                    foreach (IPAddress dns in dnsServers)
                    {
                        if (IsIPv4(dns.ToString()))
                        {
                            bool dnsFound = false;
                            foreach (KeyValuePair<NetworkInterface, IPAddress> pair in m_dDNSinfo)
                            {
                                if (pair.Value.ToString() == dns.ToString())
                                {
                                    dnsFound = true;
                                    break;
                                }
                            }
                            if (dnsFound == false)
                            {
                                //DNS address changed
                                m_dDNSinfo.Add(adapter, dns);;
                                Console.WriteLine("Adapter: {0}\n new DNS Server : {1}",
                                adapter.Description, dns.ToString());
                            }   
                        }
                    }
                }
            }
        }

        public void RegisterToDNSChanges()
        {
            try
            {
                string path = null;
                int count = 0;

                path += "(";
                foreach (KeyValuePair<NetworkInterface, IPAddress> pair in m_dDNSinfo)
                {
                    if (0 == count++)
                    {
                        path += "(KeyPath = 'SYSTEM\\\\CurrentControlSet\\\\services\\\\Tcpip\\\\Parameters\\\\Interfaces\\\\" + pair.Key.Id + "'" + " AND ValueName='NameServer')";
                        continue;
                    }
                    path += " OR (KeyPath = 'SYSTEM\\\\CurrentControlSet\\\\services\\\\Tcpip\\\\Parameters\\\\Interfaces\\\\" + pair.Key.Id + "'" + " AND ValueName='NameServer')";
                }
                path += ")";

                //@"AND KeyPath = 'SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces\\{3E6EC2F0-C690-4CDA-BA57-5710EF53BEEC}' AND ValueName='NameServer'");
                WqlEventQuery query = new WqlEventQuery(
                     "SELECT * FROM RegistryValueChangeEvent WHERE " +
                     "Hive = 'HKEY_LOCAL_MACHINE'" +
                     " AND " +
                     @path);


                m_watcher = new ManagementEventWatcher(query);
                //Console.WriteLine("Waiting for an event...");

                // Set up the delegate that will handle the change event.
                m_watcher.EventArrived += new EventArrivedEventHandler(HandleEvent);

                // Start listening for events.
                m_watcher.Start();
            }
            catch (ManagementException managementException)
            {
                Console.WriteLine("An error occurred: " + managementException.Message);
            }
        }

        private void HandleEvent(object sender, EventArrivedEventArgs e)
        {
            //Console.WriteLine("Received an event.");
            checkIFDNSChanged();
        }
    }
}

Этот код правильно извлекает сетевые адаптеры и хочет прослушивать изменения DNS для каждого сетевого адаптера, используя ManagementEventWatcher с запросом более чем одного идентификатора сетевого адаптера. Для одного сетевого адаптера он работает отлично, но при наличии двух я получаю ошибку "Произошла ошибка: не найдено" в этом механизме перехвата.

Отклоненный запрос выглядит так:

select * from RegistryValueChangeEvent where Hive = 'HKEY_LOCAL_MACHINE' AND ((KeyPath =   'SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces\\{3E6EC2F0-C690-4CDA-BA57-5710EF53BEEC}' AND ValueName='NameServer') OR (KeyPath = 'SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces\\{D92D94EF-A89E-4D73-B024-C0BD9E41FF75}' AND ValueName='NameServer'))

Успешный запрос только для одного сетевого адаптера выглядит следующим образом:

select * from RegistryValueChangeEvent where Hive = 'HKEY_LOCAL_MACHINE' AND ((KeyPath = 'SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces\\{3E6EC2F0-C690-4CDA-BA57-5710EF53BEEC}' AND ValueName='NameServer'))

Есть ли у вас идеи, почему ManagementEventWatcher отклоняет запрос для 2 разных сетевых адаптеров? Спасибо

1 ответ

Очень странный факт заключается в том, что проблема заключается в получении сетевых адаптеров.
Функция getDNSAddresses находит 2 адаптера, которые кажутся действительными, для которых настроен DNS-сервер. Эти 2 я сохраняю и создаю Wql-запрос, но один из них недействителен, и не присутствует в качестве действующего сетевого адаптера в regeditor.
Я сделал карту о том, что происходит на моем ноутбуке:

    //Existing in regeditor
Qualcomm Atheros AR8171/8175 PCI-E Gigabit Ethernet Controller (NDIS 6.20)ID: {8B9CD735-49EE-49E1-8E0F-466C02D9BB85}
Microsoft Virtual WiFi Miniport Adapter #2ID: {90968357-571E-4653-B8CD-BDF1C549BC27}
Microsoft Virtual WiFi Miniport AdapterID: {456DFC38-8F54-4AC1-BF34-C85A05A80EEA}
Intel(R) Centrino(R) Wireless-N 2230ID: {18EBEB58-873F-4801-9832-C5BF63428D92}
Bluetooth Device (Personal Area Network)ID: {54557685-9600-4DE2-B0E9-2AEB8E1DCA9B}
VMware Virtual Ethernet Adapter for VMnet1ID: {6E4C4BD2-4391-45CB-BE37-880D144EAD4A}
VMware Virtual Ethernet Adapter for VMnet8ID: {84A07569-65AA-4055-8B09-5566D0CC4972}

//NOT present in regeditor
Software Loopback Interface 1ID: {3D3783A2-703A-11DE-8C7A-806E6F6E6963}
Microsoft ISATAP Adapter #2ID: {1E3038C6-32BA-4365-B4E4-9D8953F7AA5F}
Teredo Tunneling Pseudo-InterfaceID: {6FEF71DB-470C-4F86-A358-010DB22B378E}
Microsoft ISATAP Adapter #4ID: {0032E5D4-E471-4F9B-96E1-02899AEDEFF3}
Microsoft ISATAP Adapter #7ID: {94ABD1CA-912B-4AE9-A447-DE58556162B6}
Microsoft ISATAP Adapter #6ID: {FF2CB46B-7F79-475D-84BA-D0EF92FF2A79}
Microsoft ISATAP Adapter #9ID: {A436A38A-86D2-4578-B68B-6DA6F6730D96}

//Adapters find as VALID ones as containing DNS servers
Adapter: Intel(R) Centrino(R) Wireless-N 2230
 Adapter ID:{18EBEB58-873F-4801-9832-C5BF63428D92}//this one is a VALID one with DNS server
 DNS Server : 192.168.1.1
Adapter: Microsoft ISATAP Adapter #6
 Adapter ID:{FF2CB46B-7F79-475D-84BA-D0EF92FF2A79}//this one is not found in regeditor 
 DNS Server : 192.168.1.1
Другие вопросы по тегам