使用WMI/Win32#U网络适配器配置轮询C#中的IP地址更改
我正在制作一个程序,需要为计算机的有线NIC设置一个静态IP,并且该程序无法执行下一部分(从同一网络上的另一个IP查询SNMP字符串),直到它被正确设置并可用为止,经验告诉我,这并不总是即时的。该程序是作为WinForms应用程序在VS2013上用C#编写的,函数如下所示。IP地址的实际设置工作正常,问题是在更改完成时尝试轮询。我可以运行该程序,让它设置一个IP地址(永远不要超过一个IP/子网/网关),当它仍在轮询更改时,弹出命令提示符,运行ipconfig,并查看更改是否已经完成。程序将继续挂起,直到超时。我尝试了几种不同的查询和检查IP地址的方法,包括每次通过循环重新分配NICConfig,并检查字符串[]中的任何IP地址是否匹配,但没有任何效果。我还没有将currentIPs[0]通过管道传输到文件或命令行以查看它包含的内容,但我强烈怀疑它将包含以前的IP地址。根据这篇文章,我还尝试在注册表中设置IP地址:但我所做的只是在ipconfig中的接口上给我第二个IP地址,程序仍然挂起 实际上,在进一步检查中,它的行为似乎是将IP地址/子网/网关添加到列表(字符串数组),而不是替换旧的信息,但程序甚至没有获得列表的更新版本,其中包含预期的IP。在使用上面链接中的代码处理注册表值之前,这可能不会启动,我不能确定。我似乎也无法从我的电脑配置中删除额外的IP,它们不会显示在windows ipv4配置页面中(但我在关闭多个网关时收到警告),从注册表中删除它们似乎没有任何作用,因此,如果您能帮我修复电脑的NIC配置,我将不胜感激使用WMI/Win32#U网络适配器配置轮询C#中的IP地址更改,c#,networking,wmi,ip-address,C#,Networking,Wmi,Ip Address,我正在制作一个程序,需要为计算机的有线NIC设置一个静态IP,并且该程序无法执行下一部分(从同一网络上的另一个IP查询SNMP字符串),直到它被正确设置并可用为止,经验告诉我,这并不总是即时的。该程序是作为WinForms应用程序在VS2013上用C#编写的,函数如下所示。IP地址的实际设置工作正常,问题是在更改完成时尝试轮询。我可以运行该程序,让它设置一个IP地址(永远不要超过一个IP/子网/网关),当它仍在轮询更改时,弹出命令提示符,运行ipconfig,并查看更改是否已经完成。程序将继续挂
private bool set_staticIP(string Index, string[] IP, string[] Subnet, string[] Gateway, string[] DNS)
{
string WMIQuery = String.Format("Win32_NetworkAdapterConfiguration.Index='{0}'", Index);
ManagementObject NICConfig = new ManagementObject(@"root\CIMV2", WMIQuery, null);
ManagementBaseObject inParams = null;
ManagementBaseObject outParams = null;
string[] OldIP = (string[])NICConfig["IPAddress"];
try
{
/* Set IP/Subnet mask */
inParams = NICConfig.GetMethodParameters("EnableStatic");
inParams["IPAddress"] = IP;
inParams["SubnetMask"] = Subnet;
outParams = NICConfig.InvokeMethod("EnableStatic", inParams, null);
if (outParams["ReturnValue"].ToString() != "0")
{
MessageBox.Show("Error setting IP, returned " + outParams["ReturnValue"]);
}
/* Set Gateway(s) */
inParams = NICConfig.GetMethodParameters("SetGateways");
inParams["DefaultIPGateway"] = Gateway;
inParams["GatewayCostMetric"] = new int[] {1};
outParams = NICConfig.InvokeMethod("SetGateways", inParams, null);
if (outParams["ReturnValue"].ToString() != "0")
{
MessageBox.Show("Error setting Gateway, returned " + outParams["ReturnValue"]);
}
/* Set DNS Servers */
inParams = NICConfig.GetMethodParameters("SetDNSServerSearchOrder");
inParams["DNSServerSearchOrder"] = DNS;
outParams = NICConfig.InvokeMethod("SetDNSServerSearchOrder", inParams, null);
if (outParams["ReturnValue"].ToString() != "0")
{
MessageBox.Show("Error setting DNS, returned " + outParams["ReturnValue"]);
}
bool IPMatches = false;
string[] currentIPs = null;
int timeout = 2000;
int i;
for (i = 0; i < timeout && !IPMatches; i++)
{
currentIPs = (string[])NICConfig["IPAddress"];
if (currentIPs == IP || currentIPs != OldIP)
{
IPMatches = true;
break;
}
Task.Delay(100);
}
if (i >= timeout)
{
MessageBox.Show("Timeout while setting static IP address");
}
}
catch(ManagementException e)
{
MessageBox.Show("set_static() threw exception " + e.Message);
}
return IPMatches;
}
private bool set\u staticIP(字符串索引、字符串[]IP、字符串[]子网、字符串[]网关、字符串[]DNS)
{
string WMIQuery=string.Format(“Win32_NetworkAdapterConfiguration.Index='{0}',Index”);
ManagementObject NICConfig=新的ManagementObject(@“root\CIMV2”,wmiquiry,null);
ManagementBaseObject inParams=null;
ManagementBaseObject输出参数=null;
字符串[]OldIP=(字符串[])NICConfig[“IPAddress”];
尝试
{
/*设置IP/子网掩码*/
inParams=NICConfig.GetMethodParameters(“EnableStatic”);
inParams[“IPAddress”]=IP;
inParams[“子网掩码”]=子网;
outParams=NICConfig.InvokeMethod(“EnableStatic”,inParams,null);
if(outParams[“ReturnValue”].ToString()!=“0”)
{
MessageBox.Show(“错误设置IP,返回”+输出参数[“返回值”]);
}
/*设置网关*/
inParams=NICConfig.GetMethodParameters(“设置网关”);
inParams[“DefaultIPGateway”]=网关;
inParams[“GatewayCostMetric”]=新的int[]{1};
outParams=NICConfig.InvokeMethod(“设置网关”,inParams,null);
if(outParams[“ReturnValue”].ToString()!=“0”)
{
Show(“设置网关时出错,返回”+输出参数[“返回值”]);
}
/*设置DNS服务器*/
inParams=NICConfig.GetMethodParameters(“SetDNSServerSearchOrder”);
inParams[“DNSServerSearchOrder”]=DNS;
outParams=NICConfig.InvokeMethod(“SetDNSServerSearchOrder”,inParams,null);
if(outParams[“ReturnValue”].ToString()!=“0”)
{
Show(“设置DNS时出错,返回”+输出参数[“返回值”]);
}
bool IPMatches=false;
字符串[]currentIPs=null;
int超时=2000;
int i;
对于(i=0;i=超时)
{
MessageBox.Show(“设置静态IP地址时超时”);
}
}
捕获(e)
{
Show(“set_static()抛出异常”+e.Message);
}
返回IPMatch;
}
我测试过的机器是运行Windows 7 x64的笔记本电脑,内部NIC和USB NIC的行为与此相同,而平板电脑运行Windows 8.1 x64的行为与USB NIC相同。您可以使用:
// Callback für Netzwerk-Änderungen erzeugen
NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(AddressChangedCallback);
// Callback für Netzwerk-Änderungen
void AddressChangedCallback(object sender, EventArgs e)
{
// IP is changed;
}
无论何时更改网络地址,您都会收到回调。现在,您可以检查它是否是您正在等待的地址。好的,所以我对这个问题做了更多的探讨。如果我轮询要更改的IP地址,则我尝试设置的任何IP地址都会添加到IP地址列表中。您不能使用“==”或“!=”来比较数组内容。我一直在尝试实现与您相同的目标,即使IPAddress属性更改为正确的值,更改也不一定会传播到网络堆栈,因此地址可能仍然不可用。不过,听@dieter建议的
NetworkAddressChanged
,似乎是可行的。