【问题标题】:Changing proxy settings programmatically in Windows for DSL connections在 Windows 中以编程方式更改 DSL 连接的代理设置
【发布时间】:2013-05-29 13:53:50
【问题描述】:

我目前正在编写一个需要更改 Windows 代理设置的 C# 代理程序。每个在线指南仅更改 LAN 连接的代理设置(即在 NAT 后面)。这是一个问题,因为中国的许多用户(我的目标受众)直接将 PPPoE 连接从他们的调制解调器连接到他们的计算机并使用 PPPoE 软件拨号到 DSL(是的,这很糟糕,所有监听端口都对世界,但事情就是这样)。

如何更改 DSL 代理?这令人担忧,因为查看我的用户统计数据,大约 20% 的人没有自动更改代理设置。

【问题讨论】:

    标签: c# .net networking proxy adsl


    【解决方案1】:

    这是一个实用的示例类。你可以这样使用它:

    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);
    }
    

    【讨论】:

    • 有什么方法可以找出电脑的活动连接吗?
    • 另外,我宁愿有一个纯粹的regedit.exe 解决方案。这可能吗?
    • 这个真的不一样,其他问题请多多指教(如果需要注册信息,请不要标记为C#)
    猜你喜欢
    • 2014-06-21
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 2016-01-17
    • 2021-09-26
    • 1970-01-01
    相关资源
    最近更新 更多