2013-06-03 2 views
0

В настоящее время я пишу прокси-программу C#, для которой необходимо изменить настройки прокси-сервера Windows. Каждое онлайн-руководство изменяет настройки прокси-сервера для подключения к локальной сети (т. Е. За NAT). Это проблема, так как многие пользователи в Китае (моя целевая аудитория) напрямую подключают PPPoE-соединения от своего модема к своему компьютеру и используют программное обеспечение PPPoE для набора номера до DSL (да, это надежная защита, со всеми портами прослушивания, видимыми для мир, но так обстоит дело).Изменение настроек прокси-сервера программно в Windows для DSL-подключений

Как я могу изменить прокси-сервер DSL? Это вызывает беспокойство, так как глядя на статистику моего пользователя. ~ 20% людей не получают настройки прокси-сервера автоматически.

ответ

6

Вот класс образца полезности, который делает это. Вы можете использовать его как это:

static void Main(string[] args) 
{ 
    // read direct proxy server (return null if there isn't) of the connection named "MyConn" 
    string server = ProxyUtilities.GetDirectProxyServer("MyConn"); 

    // set a direct proxy server (set to null to disable) to the connection named "MyConn" 
    ProxyUtilities.SetDirectProxyServer("MyConn", "myproxy:8080"); 
} 

А утилита класса:

public static class ProxyUtilities 
{ 
    public static string GetDirectProxyServer(string connectionName) 
    { 
     List<INTERNET_PER_CONN_OPTION> options = new List<INTERNET_PER_CONN_OPTION>(); 
     INTERNET_PER_CONN_OPTION option = new INTERNET_PER_CONN_OPTION(); 
     option.dwOption = INTERNET_PER_CONN_PROXY_SERVER; 
     options.Add(option); 

     option = new INTERNET_PER_CONN_OPTION(); 
     option.dwOption = INTERNET_PER_CONN_FLAGS; 
     options.Add(option); 

     using (var list = INTERNET_PER_CONN_OPTION_LIST.From(connectionName, options)) 
     { 
      int size = list.dwSize; 
      if (!InternetQueryOption(IntPtr.Zero, INTERNET_OPTION_PER_CONNECTION_OPTION, list, ref size)) 
       throw new Win32Exception(Marshal.GetLastWin32Error()); 

      List<INTERNET_PER_CONN_OPTION> outOptions = list.Options; 
      string proxyServer = null; 
      if ((outOptions[1].Value.dwValue & PROXY_TYPE_PROXY) != 0) 
      { 
       proxyServer = Marshal.PtrToStringUni(outOptions[0].Value.pszValue); 
      } 
      Marshal.FreeHGlobal(outOptions[0].Value.pszValue); 
      return proxyServer; 
     } 
    } 

    public static void SetDirectProxyServer(string connectionName, string proxyServer) 
    { 
     List<INTERNET_PER_CONN_OPTION> options = new List<INTERNET_PER_CONN_OPTION>(); 
     INTERNET_PER_CONN_OPTION option = new INTERNET_PER_CONN_OPTION(); 
     option.dwOption = INTERNET_PER_CONN_PROXY_SERVER; 
     option.Value.pszValue = proxyServer == null ? IntPtr.Zero : Marshal.StringToHGlobalUni(proxyServer); 
     options.Add(option); 

     option = new INTERNET_PER_CONN_OPTION(); 
     option.dwOption = INTERNET_PER_CONN_FLAGS; 
     option.Value.dwValue = proxyServer == null ? PROXY_TYPE_DIRECT : PROXY_TYPE_PROXY; 
     options.Add(option); 

     try 
     { 
      using (var list = INTERNET_PER_CONN_OPTION_LIST.From(connectionName, options)) 
      { 
       int size = list.dwSize; 
       if (!InternetSetOption(IntPtr.Zero, INTERNET_OPTION_PER_CONNECTION_OPTION, list, size)) 
        throw new Win32Exception(Marshal.GetLastWin32Error()); 
      } 
     } 
     finally 
     { 
      Marshal.FreeHGlobal(option.Value.pszValue); 
     } 
    } 

    private const int INTERNET_OPTION_PER_CONNECTION_OPTION = 75; 
    private const int INTERNET_PER_CONN_FLAGS = 1; 
    private const int INTERNET_PER_CONN_PROXY_SERVER = 2; 
    private const int PROXY_TYPE_DIRECT = 0x00000001; 
    private const int PROXY_TYPE_PROXY = 0x00000002; 

    [StructLayout(LayoutKind.Explicit)] 
    private struct INTERNET_PER_CONN_OPTION_Value 
    { 
     [FieldOffset(0)] 
     public int dwValue; 
     [FieldOffset(0)] 
     public IntPtr pszValue; 
     [FieldOffset(0)] 
     public System.Runtime.InteropServices.ComTypes.FILETIME ftValue; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    private struct INTERNET_PER_CONN_OPTION 
    { 
     public int dwOption; 
     public INTERNET_PER_CONN_OPTION_Value Value; 
    } 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
    private class INTERNET_PER_CONN_OPTION_LIST : IDisposable 
    { 
     public int dwSize; 
     public string pszConnection; 
     public int dwOptionCount; 
     public int dwOptionError; 
     public IntPtr pOptions; 

     public static INTERNET_PER_CONN_OPTION_LIST From(string name, IEnumerable<INTERNET_PER_CONN_OPTION> options) 
     { 
      INTERNET_PER_CONN_OPTION_LIST list = new INTERNET_PER_CONN_OPTION_LIST(); 
      list.pszConnection = name; 
      list.pOptions = Marshal.AllocCoTaskMem(options.Sum(o => Marshal.SizeOf(o))); 
      IntPtr current = list.pOptions; 
      foreach (var option in options) 
      { 
       Marshal.StructureToPtr(option, current, false); 
       current += Marshal.SizeOf(option); 
      } 
      list.dwSize = Marshal.SizeOf(list); 
      list.dwOptionCount = options.Count(); 
      return list; 
     } 

     public List<INTERNET_PER_CONN_OPTION> Options 
     { 
      get 
      { 
       List<INTERNET_PER_CONN_OPTION> options = new List<INTERNET_PER_CONN_OPTION>(); 
       if (pOptions != IntPtr.Zero) 
       { 
        IntPtr current = pOptions; 
        for (int i = 0; i < dwOptionCount; i++) 
        { 
         INTERNET_PER_CONN_OPTION option = (INTERNET_PER_CONN_OPTION)Marshal.PtrToStructure(current, typeof(INTERNET_PER_CONN_OPTION)); 
         current += Marshal.SizeOf(option); 
         options.Add(option); 
        } 
       } 
       return options; 
      } 
     } 

     public void Dispose() 
     { 
      if (pOptions != null) 
      { 
       Marshal.FreeCoTaskMem(pOptions); 
       pOptions = IntPtr.Zero; 
      } 
     } 
    } 

    [DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
    private extern static bool InternetQueryOption(IntPtr hInternet, int dwOption, INTERNET_PER_CONN_OPTION_LIST list, ref int lpdwBufferLength); 

    [DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
    private static extern bool InternetSetOption(IntPtr hInternet, int dwOption, INTERNET_PER_CONN_OPTION_LIST list, int lpdwBufferLength); 
} 
+0

Есть ли какой-нибудь способ, чтобы выяснить, активное соединение компьютера? – user54609

+0

Кроме того, я предпочел бы иметь чистое решение 'regedit.exe'. Это возможно? – user54609

+1

Это действительно по-другому, пожалуйста, задайте другие вопросы (и не отмечайте его как C#, если вам нужна информация реестра) –