C#WMI:向NIC添加/删除多个IP地址

时间:2012-11-26 14:36:54

标签: c# network-programming wmi ip-address

我的应用程序是C#.net Framework 3.5。

该应用程序的主要功能是:

  1. 让用户选择网络接口卡(NIC)
  2. 为用户选择的NIC分配IP地址(和子网掩码) - 我使用WMI - Win32_NetworkAdapterConfiguration类的EnableStatic方法。
  3. Process第三方C ++ exe组件开始,表现得像服务器,它将监听给定的IP地址 - 绑定功能由服务器实现,所以在Process启动时我只是给出传递正确的IP地址,然后开始收听该地址。
  4. 操作2和3可以重复无限次,因此可以为同一个NIC分配多个IP地址并拥有多个服务器,每个服务器都可以监听自己的IP地址。

    要为给定的NIC分配IP地址,我使用WMI,特别是此代码,其中adapterGUID是用户选择的NIC的GUID,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来更新分配给NIC的IP(删除不再使用的服务器之一)时使用新的IP地址列表(即:没有旧列表)杀死服务器的IP地址)发生了一件非常奇怪的事情:随机的其他一些正在运行的服务器获得一个SOCKET_ERROR并且它们的连接已关闭。

    对发生的事情有任何想法? 当我从NIC中删除未使用的 IP地址时,为什么正在运行的服务器随机获取SOCKET_ERROR? 另外,我知道可能设置一个完整的IP地址列表只是为了删除一个它不是一个真正的最佳实践:有没有办法只删除一个给定的IP地址?

    我希望这个问题足够明确。 谢谢你的时间。

1 个答案:

答案 0 :(得分: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();

注意:此命令必须在管理员中运行。