WMI Win32_NetworkAdapterConfiguration 和 SetDNSSuffixSearchOrder 方法

WMI Win32_NetworkAdapterConfiguration and SetDNSSuffixSearchOrder method

我需要从 C# 应用程序附加 DNS 后缀:

基于此工作 VB 脚本:

On Error Resume Next

strComputer = "."
arrNewDNSSuffixSearchOrder = Array("my.first.suffix", "my.second.suffix")

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\" & strComputer & "\root\cimv2")
Set colNicConfigs = objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")

For Each objNicConfig In colNicConfigs
  strDNSHostName = objNicConfig.DNSHostName
Next
WScript.Echo VbCrLf & "DNS Host Name: " & strDNSHostName

For Each objNicConfig In colNicConfigs
  WScript.Echo VbCrLf & "  Network Adapter " & objNicConfig.Index & VbCrLf & objNicConfig.Description & VbCrLf & "    DNS Domain Suffix Search Order - Before:"
  If Not IsNull(objNicConfig.DNSDomainSuffixSearchOrder) Then
    For Each strDNSSuffix In objNicConfig.DNSDomainSuffixSearchOrder
      WScript.Echo "      " & strDNSSuffix
    Next
  End If
Next

WScript.Echo VbCrLf & String(80, "-")

Set objNetworkSettings = objWMIService.Get("Win32_NetworkAdapterConfiguration")
intSetSuffixes = objNetworkSettings.SetDNSSuffixSearchOrder(arrNewDNSSuffixSearchOrder)
If intSetSuffixes = 0 Then
  WScript.Echo VbCrLf & "Replaced DNS domain suffix search order list."
ElseIf intSetSuffixes = 1 Then
  WScript.Echo VbCrLf & "Replaced DNS domain suffix search order list." & _
   VbCrLf & "    Must reboot."
Else
  WScript.Echo VbCrLf & "Unable to replace DNS domain suffix " & _
   "search order list."
End If

WScript.Echo VbCrLf & String(80, "-")

Set colNicConfigs = objWMIService.ExecQuery _
 ("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")
For Each objNicConfig In colNicConfigs
  WScript.Echo VbCrLf & "  Network Adapter " & objNicConfig.Index & VbCrLf & objNicConfig.Description & VbCrLf & "    DNS Domain Suffix Search Order - After:"
  If Not IsNull(objNicConfig.DNSDomainSuffixSearchOrder) Then
    For Each strDNSSuffix In objNicConfig.DNSDomainSuffixSearchOrder
      WScript.Echo "      " & strDNSSuffix
    Next
  End If
Next

我最终得到了这段无法工作的 C# 代码:

using System;
using System.Diagnostics;
using System.Management;

namespace ChangeDnsSuffix
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] aSuffix = { "my.first.suffix", "my.second.suffix" };
            Int32 ret = SetDNSSuffixSearchOrder(aSuffix);
        }

        private static Int32 SetDNSSuffixSearchOrder(string[] DNSDomainSuffixSearchOrder)
        {
            try
            {
                ManagementPath mp = new ManagementPath((@"\.\root\cimv2:Win32_NetworkAdapterConfiguration"));

                InvokeMethodOptions Options = new InvokeMethodOptions();
                Options.Timeout = new TimeSpan(0, 0, 10);
                ManagementClass WMIClass = new ManagementClass("Win32_NetworkAdapterConfiguration");
                ManagementBaseObject InParams = WMIClass.GetMethodParameters("SetDNSSuffixSearchOrder");
                InParams["DNSDomainSuffixSearchOrder"] = DNSDomainSuffixSearchOrder;

                ManagementBaseObject OutParams = null;
                OutParams = InvokeMethod(mp.Path,"SetDNSSuffixSearchOrder", InParams, Options);

                Int32 numericResult = Convert.ToInt32(OutParams["ReturnValue"]);
                return numericResult;

            }
            catch (Exception exception)
            {
                Debug.WriteLine(exception.Message);
                return 0;
            }
        }

        public static ManagementBaseObject InvokeMethod(string ObjectPath, string MethodName, ManagementBaseObject InParams, InvokeMethodOptions Options)
        {
            ManagementObject WMIObject = new ManagementObject(ObjectPath);
            ManagementBaseObject OutParams = WMIObject.InvokeMethod(MethodName, InParams, Options);

            if (InParams != null)
            {
                InParams.Dispose();
            }

            return OutParams;
        }  
    }
}

我尝试对代码进行了很多更改。一旦错误是 'Invalid Method',一旦代码终止了我的 VS 实例,当前错误是:

Operation is not valid due to the current state of the object.

我做了 运行 编译的应用程序和 visual studio 提升和未提升,没有区别。

非常感谢帮助!

基督教徒


根据 manuchao 的贡献,我现在有:

using System;
using System.Diagnostics;
using System.Management;
using System.Management.Instrumentation;
using System.Collections.Generic;

namespace ChangeDnsSuffix
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (ManagementObject mo in GetSystemInformation())
            {
                mo.SetPropertyValue("DNSDomainSuffixSearchOrder", new object[] { "suffix.com" });
                mo.Put();
            }
        }

        private static IEnumerable<ManagementObject> GetSystemInformation()
        {
            ManagementObjectCollection collection = null;
            ManagementScope Scope = new ManagementScope(String.Format("\\{0}\root\cimv2", "."));

            try
            {
                SelectQuery query = new SelectQuery("select * from Win32_NetworkAdapterConfiguration");
                Scope.Connect();
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(Scope, query);
                collection = searcher.Get();
            }
            catch (ManagementException ex)
            {
                Console.WriteLine(ex.Message);
            }
            catch (UnauthorizedAccessException ex)
            {
                throw new ArgumentException(ex.Message);
            }

            if (collection == null) { yield break; }

            foreach (ManagementObject obj in collection)
            {
                yield return obj;
            }
        }

        public IEnumerable<PropertyData> GetPropertiesOfManagmentObj(ManagementObject obj)
        {
            var properties = obj.Properties;
            foreach (PropertyData item in properties)
            {
                yield return item;
            }
            yield break;
        }
    }
}

结果:

'Provider is not capable of the attempted operation'

DNSDomainSuffixSearchOrder 是一个 属性 而不是方法。 如果你想设置它,你必须这样调用:

 netWorkDevice["DNSDomainSuffixSearchOrder"] = new object[] {"doamin.int", "blubb.see"};

printer.Put(); //save

下面是读取属性的代码。

我的 WMIHelper 中的方法 class。您需要导入:

using System.Management;
using System.Management.Instrumentation;

让它工作。如果您在本地计算机上使用此代码,则必须注释掉以“//Begin:”到“//End:”开头的部分

public IEnumerable<ManagementObject> GetSystemInformation()
{
        ManagementScope scope = new ManagementScope(String.Format("\\{0}\root\cimv2", "hostname"));
        ManagementObjectCollection collection = null;

        //BEGIN: This part you will need if you want to acces other computers in your network you might wanna comment this part.
        string computerName = "Hostname";
        string userName = "username";
        string password = "ThePW";

        try
        {

            var options = new ConnectionOptions
            {
                Authentication = AuthenticationLevel.Packet,
                EnablePrivileges = true,
                Impersonation = ImpersonationLevel.Impersonate,
                Username = this.UserName,
                SecurePassword = this.Password,
                Authority = "ntlmdomain:" + Environment.UserDomainName
            };
            scope.Options = options;
            //END: Part which you need to connect to remote pc

            SelectQuery query = new SelectQuery("select * from Win32_NetworkAdapterConfiguration");

            Scope.Connect();

            ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
            collection = searcher.Get();
        }
        catch (ManagementException ex)
        {
            Console.WriteLine(ex.Message);
        }
        catch (UnauthorizedAccessException ex)
        {
            throw new ArgumentException(ex.Message);
        }

        if (collection == null) { yield break; }

        foreach (ManagementObject obj in collection)
        {
            yield return obj;
        }
 }

 public IEnumerable<PropertyData> GetPropertiesOfManagmentObj(ManagementObject obj)
 {
       var properties = obj.Properties;
       foreach (PropertyData item in properties)
       {
            yield return item;
       }

       yield break;
 }

测试class

private void HelperMethod()
{
      netWorkDevice["DNSDomainSuffixSearchOrder"] = new object[] {"doamin.int", "blubb.see"};

     foreach(ManagementObject netWorkDevice in help.GetSystemInformation())
     {
          netWorkDevice["DNSDomainSuffixSearchOrder"] = new object[] {"doamin.int", "blubb.see"};
          printer.Put(); //Save

          Console.WriteLine();
          Console.WriteLine();
          Console.WriteLine("Next Device");
          Console.WriteLine();

          foreach(var prop in help.GetPropertiesOfManagmentObj(netWorkDevice))
          {
               if (prop.Name != "DNSDomainSuffixSearchOrder") { continue; }
               if (prop.Value == null) { continue; }

               foreach(var value in (string[])prop.Value)
               {
                    Console.WriteLine(prop.Name + "         " + value);
               }
          }
     }
}

我做了一些调整,下面的方法成功地在我的机器上设置了 DNS 搜索后缀:

public static Int32 SetDNSSuffixSearchOrder(string[] DNSDomainSuffixSearchOrder)
{
    try
    {
        var options = new InvokeMethodOptions();
        options.Timeout = new TimeSpan(0, 0, 10);

        var wmiClass = new ManagementClass("Win32_NetworkAdapterConfiguration");
        var inParams = wmiClass.GetMethodParameters("SetDNSSuffixSearchOrder");

        inParams["DNSDomainSuffixSearchOrder"] = DNSDomainSuffixSearchOrder;

        var outParams = wmiClass.InvokeMethod("SetDNSSuffixSearchOrder", inParams, options);

        var numericResult = Convert.ToInt32(outParams["ReturnValue"]);
        return numericResult;

    }
    catch (Exception exception)
    {
        Debug.WriteLine(exception.Message);
        return 0;
    }
}