#c# #wmi
#c# #wmi
Вопрос:
Я пытаюсь создать инструмент, который преобразует динамические настройки IPv4-адреса, шлюза и dns, предоставляемые DHCP, в статическую конфигурацию. Я пытался использовать WMI для решения этой головоломки, но у меня проблема, которую я не могу решить.
Приложение завершается, DNS и шлюз настроены, но EnableStatic
метод (для установки IP-адреса и подсети) оказался неудачным, что означает, что IP-адрес по-прежнему принимается от DHCP (с полями, выделенными серым цветом), даже если установлен шлюз по умолчанию. Как мне это исправить?
Возвращаемое значение из EnableStatic равно 70 (недопустимый IP-адрес). Странно то, что входные параметры те же, что я извлек из сетевой карты 2 секундами ранее.
Вот код (кроме GUI),http://pastebin.com/AE3dGhUz:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Management;
namespace Static_NIC_Settings_Creator
{
public partial class Form1 : Form
{
private ManagementObjectCollection queryCollection;
private string[] networkInterfaces;
private int currentNIC;
private string[] ipAddress;
private string[] subnetMask;
private string[] defaultIPGateway;
private string[] dnsServerSearchOrder;
public Form1()
{
InitializeComponent();
getNICs();
}
private void convertButton_Click(object sender, EventArgs e)
{
if (networkInterfaces.Count() > 0)
{
//Get current NIC settings
if (!getNICSettings())
{
MessageBox.Show("Retrieving current NIC settings failed.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
//Convert to static NIC settings
if (!setNICStatic())
{
MessageBox.Show("Setting NIC settings to static failed.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
private void nicSelecter_SelectedIndexChanged(object sender, EventArgs e)
{
currentNIC = nicSelecter.SelectedIndex;
}
private void getNICs()
{
//Get NICS
ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'");
queryCollection = query.Get();
//Make nic string array
int i = queryCollection.Count;
networkInterfaces = new string[i];
//Fill nic string array
i = 0;
foreach (ManagementObject mo in queryCollection)
{
networkInterfaces[i] = (String)mo["Description"];
i ;
}
//Fill dropbox with arraylist-data
nicSelecter.DataSource = networkInterfaces;
}
private Boolean getNICSettings()
{
//Get selected NIC
int i = 0;
foreach (ManagementObject mo in queryCollection)
{
//Get settings for specific NIC
if (i == currentNIC)
{
try
{
ipAddress = (String[])mo["IPAddress"];
subnetMask = (String[])mo["IPSubnet"];
defaultIPGateway = (String[])mo["DefaultIPGateway"];
dnsServerSearchOrder = (String[])mo["DNSServerSearchOrder"];
return true;
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.ToString(), "Critical: Unhandled error");
return false;
}
}
i ;
}
return false;
}
private Boolean setNICStatic()
{
//Get selected NIC
int i = 0;
foreach (ManagementObject mo in queryCollection)
{
//Get settings for specific NIC
if (i == currentNIC)
{
try
{
//Set static IP and subnet mask
ManagementBaseObject setIP;
ManagementBaseObject newIP = mo.GetMethodParameters("EnableStatic");
newIP["IPAddress"] = ipAddress;
newIP["SubnetMask"] = subnetMask;
setIP = mo.InvokeMethod("EnableStatic", newIP, null);
//Set default gateway
ManagementBaseObject setGateway;
ManagementBaseObject newGateway = mo.GetMethodParameters("SetGateways");
newGateway["DefaultIPGateway"] = defaultIPGateway;
newGateway["GatewayCostMetric"] = new int[] { 1 };
setGateway = mo.InvokeMethod("SetGateways", newGateway, null);
//Set dns servers
ManagementBaseObject setDNS;
ManagementBaseObject newDNS = mo.GetMethodParameters("SetDNSServerSearchOrder");
newDNS["DNSServerSearchOrder"] = dnsServerSearchOrder;
setDNS = mo.InvokeMethod("SetDNSServerSearchOrder", newDNS, null);
System.Windows.Forms.MessageBox.Show("Setting NIC settings returned: " setDNS);
return true;
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.ToString(), "Critical: Unhandled error");
return false;
}
}
i ;
}
//No NICs
return false;
}
} //End class
}
Есть идеи?
Ответ №1:
Может быть, вы также вводите адреса IPv6? Просто играя с PowerShell, похоже, они ему не нравятся. Возможно, вы могли бы опубликовать фактические значения, которые вводятся во время отладки, это бы очень помогло. Также, возможно, попробуйте статически ввести некоторые значения, такие как:
new string[]{"192.168.0.1"}, new string[] {"255.255.255.255"}
Также, если вам действительно не нужны C # и графический интерфейс, вы можете рассмотреть возможность использования PowerShell (конечно, требуется его установка), поскольку WMI действительно намного проще в управлении (к сожалению, у вас все еще есть эта кривая обучения).
Это всего лишь пример того, как использовать PowerShell, вы можете, по крайней мере, использовать его для некоторого тестирования:
Get-WmiObject Win32_NetworkAdapterConfiguration
Затем получите индекс вашего адаптера, затем запустите, но замените свой номер индекса:
$obj = Get-WmiObject Win32_NetworkAdapterConfiguration | where {$_.Index -eq 1}
$obj.EnableStatic("192.168.0.1", "255.255.255.0")
Чтобы получить параметры метода, просто запустите:
$obj.EnableStatic
Он вернет:
MemberType : Method
OverloadDefinitions : {System.Management.ManagementBaseObject EnableStatic(System.String[]IPAddress, System.String[] SubnetMask)}
TypeNameOfValue : System.Management.Automation.PSMethod
Value : System.Management.ManagementBaseObject EnableStatic(System.String[]IPAddress, System.String[] SubnetMask)
Name : EnableStatic
IsInstance : True
Комментарии:
1. Это было давно назревшим. Я давно отказался от этого, но теперь, когда я практикую на PS, я нашел время протестировать и приложение C #. Кажется, что-то связано с IP6, поэтому я использовал
newIP["IPAddress"] = new String[] {ipAddress[0]};
и аналогичные для подсети, чтобы получить только настройки ipv4. В любом случае, использование нескольких ip-адресов маловероятно. Отличный улов =)2. Описание свойства IPAddresses ( msdn.microsoft.com/en-us/library / … ) говорит: «Это свойство может содержать либо адреса IPv6, либо адреса IPv4». Теперь, когда вы запрашиваете его, кажется, что он содержит адреса как v4, так и v6, но, возможно, это учитывается только при попытке изменить его (используя, например, EnableStatic(). Я сам заметил ошибку 70, если вы используете смешанные адреса с EnableStatic ().
Ответ №2:
Еще один совет для тех, кто может наткнуться на это в поиске…
Если вашему текущему IP-адресу назначен DHCP, а EnableStatic () возвращает коды ошибок 2147944122 или 2147944117, убедитесь, что служба dhcp (DHCP-клиент) в Windows включена и запущена.
Я обнаружил, что переключение с одного статического адреса на другой с помощью EnableStatic () работает нормально. Но если у вас есть динамический адрес, а служба DHCP отключена (возможно, из соображений безопасности), то EnableStatic() работать не будет.
Добавление этого решения в Интернет на случай, если это сэкономит кому-то время в будущем.