2011-03-05 35 views

回答

2

如果您可以使用WMI,則有Win32_NetworkAdapterConfiguration類。如果您需要普通的舊C API,我發現this(「設置默認網關地址」靠近底部)。

+0

對不起,我的錯誤。這些功能還需要Windows Vista。 – chacham15 2011-03-07 09:21:41

+0

只需從函數和結構名稱中刪除2;例如GetIpForwardTable(),DeleteIpForwardEntry()等等。這些函數和結構返回到Windows 2000. – Luke 2011-03-07 12:37:48

1

GetAdaptersInfo()GetAdaptersAddresses()函數都返回每個適配器的網關信息。

+0

它們會在您編譯爲vista或更高版本時執行。 – chacham15 2011-03-07 09:07:21

+0

'GetAdaptersInfo()'在XP SP3上爲我返回網關信息。 – 2011-03-08 08:26:05

0

注意:Win32_NetworkAdapterConfiguration :: SetGateways()將設置網關指定的參數,其中存在網關將被覆蓋。

但是:刪除似乎沒有使用SetGateways()WMI呼叫時工作網關(S) - 在我的情況下,調用返回成功,但網關仍然存在。似乎有很多人看到了這一點(在StringArray中設置NULL字符串或爲StringArray傳遞NULL都沒有幫助)。

在我的情況下,我開始使用WMI方式(很可能是因爲EnableDHCP()),還需要實現Luke建議的WINAPI方式,以便通過網關消除災難。非常感謝盧克!上述

-1
public enum ForwardType 
    { 
     Other = 1, 
     Invalid = 2, 
     Direct = 3, 
     Indirect = 4 
    } 

    public enum ForwardProtocol 
    { 
     Other = 1, 
     Local = 2, 
     NetMGMT = 3, 
     ICMP = 4, 
     EGP = 5, 
     GGP = 6, 
     Hello = 7, 
     RIP = 8, 
     IS_IS = 9, 
     ES_IS = 10, 
     CISCO = 11, 
     BBN = 12, 
     OSPF = 13, 
     BGP = 14, 
     NT_AUTOSTATIC = 10002, 
     NT_STATIC = 10006, 
     NT_STATIC_NON_DOD = 10007 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct MIB_IPFORWARDROW 
    { 
     public uint dwForwardDest; 
     public uint dwForwardMask; 
     public int dwForwardPolicy; 
     public uint dwForwardNextHop; 
     public int dwForwardIfIndex; 
     public ForwardType dwForwardType; 
     public ForwardProtocol dwForwardProto; 
     public int dwForwardAge; 
     public int dwForwardNextHopAS; 
     public int dwForwardMetric1; 
     public int dwForwardMetric2; 
     public int dwForwardMetric3; 
     public int dwForwardMetric4; 
     public int dwForwardMetric5; 

     public static List<MIB_IPFORWARDROW> FromByteArray(byte[] buffer) 
     { 
      List<MIB_IPFORWARDROW> ret = new List<MIB_IPFORWARDROW>(); 

      int n = 
       (buffer[3] << 24) + 
       (buffer[2] << 16) + 
       (buffer[1] << 8) + 
       (buffer[0] << 0); 

      int offset = sizeof(int); 
      for (int i = 0; i < n; i++) 
      { 
       MIB_IPFORWARDROW map = new MIB_IPFORWARDROW(); 
       IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(map)); 
       Marshal.StructureToPtr(map, ptr, false); 
       Marshal.Copy(buffer, offset, ptr, Marshal.SizeOf(map)); 
       map = (MIB_IPFORWARDROW)Marshal.PtrToStructure(ptr, typeof(MIB_IPFORWARDROW)); 
       Marshal.FreeHGlobal(ptr); 
       ret.Add(map); 
       offset += Marshal.SizeOf(map); 
      } 
      return ret; 
     } 
    } 

    [DllImport("Iphlpapi.dll", CharSet = CharSet.Auto)] 
    public static extern int GetIpForwardTable(byte[] pIpForwardTable, ref ulong pdwSize, bool bOrder); 

    [DllImport("Iphlpapi.dll", CharSet = CharSet.Auto)] 
    public static extern int DeleteIpForwardEntry(ref MIB_IPFORWARDROW pRoute); 

    [DllImport("Iphlpapi.dll", CharSet = CharSet.Auto)] 
    public static extern int SetIpForwardEntry(ref MIB_IPFORWARDROW pRoute); 

    private static uint IPToUIntR(IPAddress ip) 
    { 
     uint ret = 0; 
     byte[] ipBytes = ip.GetAddressBytes(); 

     ret += (uint)ipBytes[0] << 24; 
     ret += (uint)ipBytes[1] << 16; 
     ret += (uint)ipBytes[2] << 8; 
     ret += (uint)ipBytes[3]; 

     return ret; 
    } 

    public static List<MIB_IPFORWARDROW> GetIPForwardTable(int index) 
    { 
     List<MIB_IPFORWARDROW> ret = new List<MIB_IPFORWARDROW>(); 
     ulong size = 0; 
     int err = GetIpForwardTable(null, ref size, false); 
     byte[] buffer = new byte[size]; 
     err = GetIpForwardTable(buffer, ref size, false); 

     if (err != 0) 
     { 
      throw new System.ComponentModel.Win32Exception(err, $"GetIPForwardTable return with error code {err}"); 
     } 

     foreach (MIB_IPFORWARDROW mipr in MIB_IPFORWARDROW.FromByteArray(buffer)) 
     { 
      if (mipr.dwForwardIfIndex != index) 
      { 
       continue; 
      } 
      ret.Add(mipr); 
     } 
     return ret; 
    } 

    public static void SetDefaultGateway(int index, string gateway) 
    { 
     int err; 
     int i; 
     List<MIB_IPFORWARDROW> l = GetIPForwardTable(index); 
     MIB_IPFORWARDROW mipr = new MIB_IPFORWARDROW(); 
     for (i = 0; i < l.Count; ++i) 
     { 
      // 0.0.0.0 default gateway 
      if (l[i].dwForwardDest != 0) 
      { 
       continue; 
      } 

      mipr = l[i]; 
      err = DeleteIpForwardEntry(ref mipr); 
      if (err != 0) 
      { 
       throw new System.ComponentModel.Win32Exception(err, $"DeleteIpForwardEntry return with error code {err}"); 
      } 
      break; 
     } 
     mipr.dwForwardNextHop = IPToUIntR(IPAddress.Parse(gateway)); 

     err = SetIpForwardEntry(ref mipr); 
     if (err != 0) 
     { 
      throw new System.ComponentModel.Win32Exception(err, $"DeleteIpForwardEntry return with error code {err}"); 
     } 
    } 

代碼使用pinvokes使用iphelper功能在.NET中,所以,忘掉pinvokes和使用代碼爲您的Win32應用程序的參考。

https://msdn.microsoft.com/en-us/library/windows/desktop/aa366363(v=vs.85).aspx

編輯: 您可以使用下面的代碼,以獲得適配器信息。並在需要使用SetDefaultGateway時使用Index字段。

const int MAX_ADAPTER_ADDRESS_LENGTH = 8; 
    const int MAX_ADAPTER_DESCRIPTION_LENGTH = 128; 
    const int MAX_ADAPTER_NAME_LENGTH = 256; 
    const int MAX_ADAPTER_NAME = 128; 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
    public struct IP_ADDRESS_STRING 
    { 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] 
     public string Address; 
    } 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
    public struct IP_ADDR_STRING 
    { 
     public IntPtr Next; 
     public IP_ADDRESS_STRING IpAddress; 
     public IP_ADDRESS_STRING IpMask; 
     public ulong Context; 
    } 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
    public struct IP_ADAPTER_INFO 
    { 
     public IntPtr Next; 
     public Int32 ComboIndex; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_ADAPTER_NAME_LENGTH + 4)] 
     public string AdapterName; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_ADAPTER_DESCRIPTION_LENGTH + 4)] 
     public string AdapterDescription; 
     public UInt32 AddressLength; 
     [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_ADAPTER_ADDRESS_LENGTH)] 
     public byte[] Address; 
     public Int32 Index; 
     public UInt32 Type; 
     public UInt32 DhcpEnabled; 
     public IntPtr CurrentIpAddress; 
     public IP_ADDR_STRING IpAddressList; 
     public IP_ADDR_STRING GatewayList; 
     public IP_ADDR_STRING DhcpServer; 
     public bool HaveWins; 
     public IP_ADDR_STRING PrimaryWinsServer; 
     public IP_ADDR_STRING SecondaryWinsServer; 
     public Int32 LeaseObtained; 
     public Int32 LeaseExpires; 
    } 

    [DllImport("iphlpapi.dll", CharSet = CharSet.Ansi)] 
    static extern int GetAdaptersInfo(byte[] pAdapterInfo, ref ulong pBufOutLen); 

    public static List<IP_ADAPTER_INFO> GetAllAdapters() 
    { 
     List<IP_ADAPTER_INFO> ret = new List<IP_ADAPTER_INFO>(); 

     ulong size = 0; 
     int err = GetAdaptersInfo(null, ref size); 
     byte[] buffer = new byte[size]; 
     err = GetAdaptersInfo(buffer, ref size); 

     if (err != 0) 
     { 
      throw new System.ComponentModel.Win32Exception(err, $"GetInterfaceInfo return with error code {err}"); 
     } 

     GCHandle gc = GCHandle.Alloc(buffer, GCHandleType.Pinned); 
     IntPtr pEntry = gc.AddrOfPinnedObject(); 
     do 
     { 
      IP_ADAPTER_INFO entry = (IP_ADAPTER_INFO)Marshal.PtrToStructure(pEntry, typeof(IP_ADAPTER_INFO)); 

      ret.Add(entry); 

      pEntry = entry.Next; 
     } 
     while (pEntry != IntPtr.Zero); 

     gc.Free(); 

     return ret; 
    } 
+0

儘管這個鏈接可能回答這個問題,但最好在這裏包含答案的重要部分,並提供參考鏈接。如果鏈接頁面更改,則僅鏈接答案可能會失效。 - [來自評論](/ review/low-quality-posts/17580508) – 2017-10-10 09:34:20