【问题标题】:Problems using the WMI EnableStatic method使用 WMI EnableStatic 方法的问题
【发布时间】:2011-04-11 20:57:59
【问题描述】:

我正在尝试创建一个工具,将动态 DHCP 提供的 IPv4 地址、网关和 dns 设置转换为静态配置。我尝试使用 WMI 来解决这个难题,但我有一个我无法弄清楚的问题。

应用程序完成,DNS 和网关已配置,但 EnableStatic 方法(设置 IP 地址和子网)不成功,这意味着即使默认网关已设置。我该如何解决这个问题?

EnableStatic 的 ReturnValue 是 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
}

有什么想法吗?

【问题讨论】:

    标签: c# wmi


    【解决方案1】:

    难道你也在输入IPv6 地址?只是玩弄 PowerShell 似乎不喜欢它们。也许您可以发布在调试时输入的实际值,这会很有帮助。也可以尝试静态输入一些值,例如:

    new string[]{"192.168.0.1"}, new string[] {"255.255.255.255"}
    

    此外,除非您真的非常需要 C# 和 GUI,否则您可能需要考虑使用 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
    

    【讨论】:

    • 这早就该了。我很久以前就放弃了,但现在当我在 PS 上练习时,我也花时间测试了 C# 应用程序。似乎有一些关于 IP6 的东西,所以我使用newIP["IPAddress"] = new String[] {ipAddress[0]}; 和类似的子网来获取 ipv4 设置。无论如何,多个ipaddresses不太可能使用。很棒的收获 =)
    • IPAddresses 属性 (msdn.microsoft.com/en-us/library/…) 的描述说:“该属性可以包含 IPv6 地址或 IPv4 地址”。现在,当您查询它时,它似乎同时包含 v4 和 v6 地址,但它可能仅在您尝试更改它时才计数(使用例如 EnableStatic()。如果您将混合地址与 EnableStatic( )。
    【解决方案2】:

    对于那些可能在搜索中偶然发现的人的另一个提示...

    如果您当前的 IP 地址是 DHCP 分配的,并且 EnableStatic() 返回 2147944122 或 2147944117 错误代码,请验证 Windows 中的 dhcp 服务(DHCP 客户端)是否已启用并启动。

    我发现使用 EnableStatic() 从一个静态地址切换到另一个静态地址可以正常工作。但是如果你有一个动态地址,并且 DHCP 服务被禁用(可能是出于安全原因),那么 EnableStatic() 将不起作用。

    将此解决方案添加到互联网,以防将来节省时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-22
      • 1970-01-01
      • 2013-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多