2013-06-03 4 views
0

현재 Windows 프록시 설정을 변경해야하는 C# 프록시 프로그램을 작성하고 있습니다. 모든 온라인 가이드는 LAN 연결 (즉, 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#으로 표시하지 마십시오) –