2015-04-20 218 views
0

我正在製作一個程序,需要將靜態IP設置到計算機的有線網卡,並且程序無法執行下一部分(從另一個查詢SNMP字符串IP在同一個網絡上),直到它被正確地設置和使用,這些經驗告訴我並不總是即時的。該程序是作爲WinForms應用程序在VS2013上用C#編寫的,該函數如下所示。 IP地址的實際設置完美地工作,問題是試圖輪詢更改何時完成。我可以運行程序,讓它設置一個IP地址(永遠不會超過一個IP /子網/網關),並且在它仍在輪詢更改時,彈出打開命令提示符,運行ipconfig並查看已經發生更改經歷了。該計劃將繼續掛起,直到超時。我嘗試了幾種不同的方法來查詢和檢查IP地址,包括每次通過循環重新分配NICConfig並檢查兩個字符串[]中的IP地址是否匹配,什麼都不起作用。我還沒有將當前的IP [0]傳送到文件或命令行以查看它包含的內容,但我強烈懷疑它將包含以前的IP地址。我也嘗試在註冊表中設置IP地址,這個帖子是:Why does applying a static IP address via WMI work just once?,但是我所做的只是在ipconfig中爲該接口提供了第二個IP地址,該程序仍然懸掛着。使用WMI/Win32_NetworkAdapterConfiguration查詢C#中的IP地址更改

實際上,在進一步的檢查中,看起來行爲是將IP地址/子網/網關添加到列表(字符串數組),而不是替換舊的信息,但程序甚至沒有更新帶有預期IP的列表版本。這可能沒有開始,直到使用上面的鏈接代碼搞亂註冊表值後,我無法確定。我似乎也無法從我的PC配置中刪除多餘的IP,它們不會顯示在windows ipv4配置頁面中(但在關閉多個網關時會發出警告),並將它們從註冊表中移除什麼也不做 - 所以任何幫助修復我的電腦的網卡配置也將不勝感激。

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

我測試過這個機器上運行的是Windows 7 X64的一臺筆記本電腦,我得到的內部NIC和USB網卡,並運行Windows 8.1的x64與同USB網卡平板電腦相同的行爲。

+0

好的,所以我對此做了更多的探索。看來,如果我輪詢IP地址改變,那麼無論我嘗試設置的IP地址是否添加到IP地址列表中。 –

+0

您無法使用'=='或'!='來比較數組內容。 我一直在試圖完成和你一樣的工作,即使IPAddress屬性更改爲正確的值,但更改還未傳播到網絡堆棧,因此地址可能仍然不可用。聽到下面@dieter建議的'NetworkAddressChanged'似乎工作。 –

回答

0

您可以使用:

// 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; 
} 

你會得到每當網絡ADRESS改變回調。現在你可以檢查它是否是你正在等待的地址。