2012-11-26 60 views
0

我的應用程序是C#.net Framework 3.5。C#WMI:向NIC添加/刪除多個IP地址

應用程序的主要功能是:

  1. 讓用戶選擇的網絡接口卡(NIC)
  2. 分配給選定的NIC的IP地址(和子網掩碼)的用戶 - 我使用WMI - 啓用Win32_NetworkAdapterConfiguration類的靜態方法。
  3. 開始通過Process第三方C++ EXE組件,表現得像一臺服務器,這將是監聽指定IP地址 - 綁定功能由服務器實現的,因此在過程開始了,我只是給通過正確的IP地址,並開始在那一個上收聽。

操作2和3可以重複無限次數,因此可以爲同一個NIC分配多個IP地址並且有多個服務器,每個服務器都監聽自己的IP地址。

分配IP地址給定的NIC我使用WMI,特別是這個代碼,其中adapterGUID是用戶的GUID選定的NIC和newSettings它所持有的IP和子網掩碼的列表類:

public static bool ChangeNetworkInterfaceIPs(string adapterGUID, IpSettings newSettings) 
    { 
     try 
     { 
      if (String.IsNullOrEmpty(adapterGUID)) 
        throw new ArgumentException("adapterGUID"); 

       ManagementBaseObject inPar = null; 

       ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration"); 
       ManagementObjectCollection moc = mc.GetInstances(); 
       ManagementObject moTarget = null; 

       //Look for the correct network interface 
       foreach (ManagementObject mo in moc) 
       { 
        //find the target management object 
        if ((string) mo["SettingID"] == adapterGUID) 
        { 
         moTarget = mo; 
         break; 
        } 
       } 
       if (moTarget == null) 
       { 
        mc = null; 
        return false; 
       } 

       //we found the correct NIC. Save the current gateways, dns and wins 
       object winsSecondary = moTarget.GetPropertyValue("WINSSecondaryServer"); 
       object gateways = moTarget.GetPropertyValue("DefaultIPGateway"); 
       object dnsDomain = moTarget.GetPropertyValue("DNSDomain"); 
       object dnsServers = moTarget.GetPropertyValue("DNSServerSearchOrder"); 
       object winsPrimary = moTarget.GetPropertyValue("WINSPrimaryServer"); 

       if (newSettings.DHCP) 
       { 
        inPar = moTarget.GetMethodParameters("EnableDHCP"); 
        moTarget.InvokeMethod("EnableDHCP", inPar, null); 
       } 
       else 
       { 
        inPar = moTarget.GetMethodParameters("EnableStatic"); 
        inPar["IPAddress"] = newSettings.Ips; 
        inPar["SubnetMask"] = newSettings.Netmasks; 
        moTarget.InvokeMethod("EnableStatic", inPar, null); 
       } 

       //restore the gateways, dns and wins 
       if (gateways != null && !newSettings.DHCP) 
       { 
        inPar = moTarget.GetMethodParameters("SetGateways"); 
        inPar["DefaultIPGateway"] = gateways; 
        outPar = moTarget.InvokeMethod("SetGateways", inPar, null); 
       } 
       if (dnsDomain != null && !newSettings.DHCP) 
       { 
        inPar = moTarget.GetMethodParameters("SetDNSDomain"); 
        inPar["DNSDomain"] = dnsDomain; 
        outPar = moTarget.InvokeMethod("SetDNSDomain", inPar, null); 
       } 
       if (dnsServers != null && !newSettings.DHCP) 
       { 
        //Do not restore DNS Servers in case of DHCP. Will be retrieved from DHCP Server 
        inPar = moTarget.GetMethodParameters("SetDNSServerSearchOrder"); 
        inPar["DNSServerSearchOrder"] = dnsServers; 
        outPar = moTarget.InvokeMethod("SetDNSServerSearchOrder", inPar, null); 
       } 
       if (winsPrimary != null && !newSettings.DHCP) 
       { 
        inPar = moTarget.GetMethodParameters("SetWINSServer"); 
        inPar["WINSPrimaryServer"] = winsPrimary; 
        if (winsSecondary != null) 
        { 
         inPar["WINSSecondaryServer"] = winsSecondary; 
        } 
        outPar = moTarget.InvokeMethod("SetWINSServer", inPar, null); 
       } 

       return true; 
     } 
     catch 
     { 
      return false; 
     } 
    } 

現在,我的問題來了,當用戶想殺死一個活動服務器。 在服務器關閉時,我必須從NIC中刪除服務器正在監聽的IP地址。

殺死進程不是問題,但是當我打電話給ChangeNetworkInterfaceIPs時,使用新的IP地址列表(即:舊列表)來更新分配給NIC的IP(刪除不再使用的服務器之一)沒有被殺的服務器的IP地址)發生了一些非常奇怪的事情:隨機的其他一些正在運行的服務器得到一個SOCKET_ERROR並且它們的連接被關閉。

有什麼想法發生了什麼? 當我從NIC中刪除未使用的 IP地址時,爲什麼運行中的服務器會隨機獲取SOCKET_ERROR? 此外,我知道可能設置一個IP地址的整個列表只是爲了刪除一個它不是一個真正的最佳實踐:有沒有辦法只刪除給定的IP地址?

我希望問題很清楚。 謝謝你的時間。

回答

0

我不回答在崗的所有問題,但張貼這可能是像我這樣的初學者很有幫助。

問:有沒有辦法只刪除給定的IP地址?
答:運行netsh命令作爲一個過程在C#

Process p = new Process(); 
p.StartInfo.UseShellExecute = false; 
p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; 
p.StartInfo.RedirectStandardOutput = true; 
p.StartInfo.FileName = "netsh"; 
p.StartInfo.Arguments = "netsh interface ipv4 delete address \"my NIC Name\" addr=192.168.1.1"; 
p.Start(); 
string response = p.StandardOutput.ReadToEnd(); 
p.Close(); 

注:此命令在管理員必須跑。