2014-10-13 1 views
0

2 개의 네트워크 어댑터에 대한 DNS 변경 사항을 감지하려고합니다.
win 7 64 비트 시스템에 C# .net 4.0을 사용하고 있습니다.
(RegisterToDNSChanges 내부) 네트워크 어댑터의 레지스트리 키 우승을 청취 코드 :이 코드는 올바르게 네트워크 어댑터를 추출하기위한 쿼리와 ManagementEventWatcher를 사용하여 모든 네트워크 어댑터의 DNS 변경을 듣고 싶어두 개 이상의 네트워크 어댑터에 대해 WqlEventQuery 쿼리를 작성하지 못했습니다. C#

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

을 두 개 이상의 네트워크 어댑터 ID. 1 개의 단일 네트워크 어댑터의 경우 완벽하게 작동하지만 2 일 때 해당 캐치 메커니즘에 "오류가 발생했습니다 : 찾을 수 없음"오류가 표시됩니다.

거부 ​​된 쿼리는 다음과 같습니다

만 1 네트워크 어댑터의 succesfull 쿼리는 다음과 같습니다
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에 대한 쿼리를 거부하는 이유 어떤 생각을 가지고 있습니까 다른 네트워크 어댑터? 고맙습니다.

답변

0

매우 이상한 사실은 네트워크 어댑터를 얻는 데 문제가 있다는 것입니다.
함수 getDNSAddresses는 유효한 것으로 보이며 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 
관련 문제