zoukankan      html  css  js  c++  java
  • C#设置IE代理及遇到问题的解决方案

      起初使用的方法是修改完一次代理之后就不能继续修改,需要重新启动一次进程才可以,最初代码是:

     private void ShowProxyInfo()
            {
                if (!GetProxyStatus())
                {
                    lblInitInfo.Text = "代理未启用:";
                }
                else
                {
                    lblInitInfo.Text = "当前使用的代理是:" + GetProxyServer();
                }
    
            }
    
            private void InitProxyData()
            {
                List<string> proxyList = new List<string>{
                   "http://web-proxy.cup.hp.com:8080","http://proxy.compaq.com:8080"
               };
                combProxyList.DataSource = proxyList;
                combProxyList.SelectedIndex = 0;
            }
            public void SetProxy(string proxy)
            {
                //打开注册表 
                //RegistryKey regKey = Registry.CurrentUser;
                //string SubKeyPath = "Software\Microsoft\Windows\CurrentVersion\Internet Settings";
                //RegistryKey optionKey = regKey.OpenSubKey(SubKeyPath, true);             //更改健值,设置代理, 
                //optionKey.SetValue("ProxyEnable", 1);
                //optionKey.SetValue("ProxyServer", proxy);
    
                ////激活代理设置【用于即使IE没有关闭也能更新当前打开的IE中的代理设置。】   
                //InternetSetOption(0, 39, IntPtr.Zero, 0);
                //InternetSetOption(0, 37, IntPtr.Zero, 0);
                //regKey.Flush(); //刷新注册表  
                //regKey.Close();
                //ShowProxyInfo();
    
                using (RegistryKey regKey = Registry.CurrentUser)
                {
                    string SubKeyPath = "Software\Microsoft\Windows\CurrentVersion\Internet Settings";
                    RegistryKey optionKey = regKey.OpenSubKey(SubKeyPath, true);             //更改健值,设置代理
                    optionKey.SetValue("ProxyEnable", 1);
                    optionKey.SetValue("ProxyServer", proxy);
                    //激活代理设置【用于即使IE没有关闭也能更新当前打开的IE中的代理设置。】   
                    InternetSetOption(0, 39, IntPtr.Zero, 0);
                    InternetSetOption(0, 37, IntPtr.Zero, 0);
                    regKey.Flush(); //刷新注册表  
                    ShowProxyInfo();
                }
    
            }
    
            public void DisableProxy()
            {
                //打开注册表 
                RegistryKey regKey = Registry.CurrentUser;
                string SubKeyPath = "Software\Microsoft\Windows\CurrentVersion\Internet Settings";
                RegistryKey optionKey = regKey.OpenSubKey(SubKeyPath, true);             //更改健值,设置代理, 
                optionKey.SetValue("ProxyEnable", 0);
                regKey.Flush(); //刷新注册表  
                InternetSetOption(0, 39, IntPtr.Zero, 0);
                InternetSetOption(0, 37, IntPtr.Zero, 0);
                regKey.Close();
                ShowProxyInfo();
            }
    
            [DllImport(@"wininet", SetLastError = true, CharSet = CharSet.Auto,
              EntryPoint = "InternetSetOption",
              CallingConvention = CallingConvention.StdCall)]
            public static extern bool InternetSetOption(
            int hInternet, int dmOption, IntPtr lpBuffer, int dwBufferLength);
    
            private void btnSetProxy_Click(object sender, EventArgs e)
            {
                string proxyStr = combProxyList.Text.Trim();
                SetProxy(proxyStr);
                var currentProxy = GetProxyServer();
                if (currentProxy == proxyStr && GetProxyStatus())
                {
                    lblInfo.Text = "设置代理:" + proxyStr + "成功!";
                    lblInfo.ForeColor = Color.Green;
                }
                else
                {
                    if (!GetProxyStatus())
                    {
                        lblInfo.Text = "设置代理:" + proxyStr + "代理未启用!";
    
                    }
                    else
                    {
                        lblInfo.Text = "设置代理:" + proxyStr + "失败,正在使用" + currentProxy + "代理,请重试!";
    
                    }
                    lblInfo.ForeColor = Color.Red;
                }
                ShowProxyInfo();
    
            }
    
            /// <summary>
            /// 获取正在使用的代理
            /// </summary>
            /// <returns></returns>
            private string GetProxyServer()
            {
                //打开注册表 
                RegistryKey regKey = Registry.CurrentUser;
                string SubKeyPath = "Software\Microsoft\Windows\CurrentVersion\Internet Settings";
                RegistryKey optionKey = regKey.OpenSubKey(SubKeyPath, true);             //更改健值,设置代理, 
                string actualProxy = optionKey.GetValue("ProxyServer").ToString();
                regKey.Close();
                return actualProxy;
            }
    
            private bool GetProxyStatus()
            {
                //打开注册表 
                RegistryKey regKey = Registry.CurrentUser;
                string SubKeyPath = "Software\Microsoft\Windows\CurrentVersion\Internet Settings";
                RegistryKey optionKey = regKey.OpenSubKey(SubKeyPath, true);             //更改健值,设置代理, 
                int actualProxyStatus = Convert.ToInt32(optionKey.GetValue("ProxyEnable"));
                regKey.Close();
                return actualProxyStatus == 1 ? true : false;
            }
    
            //成功返回true,错误返回false  
            public Boolean prcessBaidu()
            {
                HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create("http://www.163.com");
                myRequest.Method = "POST"//采用post方式提交访问163主页 // Get response      
                try//当无法访问163网站时,下面的对象会有错误产生,所以用try..catch处理掉这些异常     
                {
                    Stream newStream = myRequest.GetRequestStream();//获取请求流     // Send the data.         
                    newStream.Close();//关闭请求流 
                    HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();//获取应答对象    
                    StreamReader reader = new StreamReader(myResponse.GetResponseStream());//获取应答流     
                    string content = reader.ReadToEnd();//将流对象读取到string 中 
                    if (content.IndexOf("http://reg.163.com") > -1)//如果访问网站成功,则网页中包含置顶的关键字符串“http://reg.163.com”表示访问网页成功    
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                catch (Exception ex)
                {
                    return false;
                }
                return false;
            }
    
            private void btnDisableProxy_Click(object sender, EventArgs e)
            {
                DisableProxy();
    
                if (!GetProxyStatus())
                {
                    lblInfo.Text = "取消代理完成!";
                    lblInfo.ForeColor = Color.Green;
                }
                else
                {
                    lblInfo.Text = "取消失败,正在使用代理" + GetProxyServer();
                    lblInfo.ForeColor = Color.Red;
                }
                ShowProxyInfo();
            }
    
            private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
            {
    
            }
    
            private void btnTestProxy_Click(object sender, EventArgs e)
            {
                string proxyStr = combProxyList.SelectedText;
                SetProxy(proxyStr);
                if (prcessBaidu())
                {
                    MessageBox.Show("代理可以正常访问。");
                }
                else
                {
                    MessageBox.Show("目前无法使用代理!");
                }
                ShowProxyInfo();
            }

      有网友的结果是说在window7下, 在一个进程中, 设置和取消不能都执行,---- 要么设置,要么取消。 但如果第一次运行时,只进行设置代理,退出后再进运行,只进行取消,这是没有问题的。简单说说他给出的解决方案:每次设置或取消代理时,都新建一个进程,在新的进程中处理,处理完之后关掉进程。参考http://blog.csdn.net/debug__boy/article/details/8432879提供新的解决方案,国外大神的文章http://huddledmasses.org/setting-windows-internet-connection-proxy-from-c/:代码如下:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace IEProxyManagment
    {
       
        public class IEProxySetting
        {
            public static bool UnsetProxy()
            {
                return SetProxy(null, null);
            }
            public static bool SetProxy(string strProxy)
            {
                return SetProxy(strProxy, null);
            }
    
            public static bool SetProxy(string strProxy, string exceptions)
            {
                InternetPerConnOptionList list = new InternetPerConnOptionList();
    
                int optionCount = string.IsNullOrEmpty(strProxy) ? 1 : (string.IsNullOrEmpty(exceptions) ? 2 : 3);
                InternetConnectionOption[] options = new InternetConnectionOption[optionCount];
                // USE a proxy server ...
                options[0].m_Option = PerConnOption.INTERNET_PER_CONN_FLAGS;
                options[0].m_Value.m_Int = (int)((optionCount < 2) ? PerConnFlags.PROXY_TYPE_DIRECT : (PerConnFlags.PROXY_TYPE_DIRECT | PerConnFlags.PROXY_TYPE_PROXY));
                // use THIS proxy server
                if (optionCount > 1)
                {
                    options[1].m_Option = PerConnOption.INTERNET_PER_CONN_PROXY_SERVER;
                    options[1].m_Value.m_StringPtr = Marshal.StringToHGlobalAuto(strProxy);
                    // except for these addresses ...
                    if (optionCount > 2)
                    {
                        options[2].m_Option = PerConnOption.INTERNET_PER_CONN_PROXY_BYPASS;
                        options[2].m_Value.m_StringPtr = Marshal.StringToHGlobalAuto(exceptions);
                    }
                }
    
                // default stuff
                list.dwSize = Marshal.SizeOf(list);
                list.szConnection = IntPtr.Zero;
                list.dwOptionCount = options.Length;
                list.dwOptionError = 0;
    
    
                int optSize = Marshal.SizeOf(typeof(InternetConnectionOption));
                // make a pointer out of all that ...
                IntPtr optionsPtr = Marshal.AllocCoTaskMem(optSize * options.Length);
                // copy the array over into that spot in memory ...
                for (int i = 0; i < options.Length; ++i)
                {
                    IntPtr opt = new IntPtr(optionsPtr.ToInt32() + (i * optSize));
                    Marshal.StructureToPtr(options[i], opt, false);
                }
    
                list.options = optionsPtr;
    
                // and then make a pointer out of the whole list
                IntPtr ipcoListPtr = Marshal.AllocCoTaskMem((Int32)list.dwSize);
                Marshal.StructureToPtr(list, ipcoListPtr, false);
    
                // and finally, call the API method!
                int returnvalue = NativeMethods.InternetSetOption(IntPtr.Zero,
                   InternetOption.INTERNET_OPTION_PER_CONNECTION_OPTION,
                   ipcoListPtr, list.dwSize) ? -1 : 0;
                if (returnvalue == 0)
                {  // get the error codes, they might be helpful
                    returnvalue = Marshal.GetLastWin32Error();
                }
                // FREE the data ASAP
                Marshal.FreeCoTaskMem(optionsPtr);
                Marshal.FreeCoTaskMem(ipcoListPtr);
                if (returnvalue > 0)
                {  // throw the error codes, they might be helpful
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
    
                return (returnvalue < 0);
            }
        }
    
        #region WinInet structures
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct InternetPerConnOptionList
        {
            public int dwSize;               // size of the INTERNET_PER_CONN_OPTION_LIST struct
            public IntPtr szConnection;         // connection name to set/query options
            public int dwOptionCount;        // number of options to set/query
            public int dwOptionError;           // on error, which option failed
            //[MarshalAs(UnmanagedType.)]
            public IntPtr options;
        };
    
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct InternetConnectionOption
        {
            static readonly int Size;
            public PerConnOption m_Option;
            public InternetConnectionOptionValue m_Value;
            static InternetConnectionOption()
            {
                InternetConnectionOption.Size = Marshal.SizeOf(typeof(InternetConnectionOption));
            }
    
            // Nested Types
            [StructLayout(LayoutKind.Explicit)]
            public struct InternetConnectionOptionValue
            {
                // Fields
                [FieldOffset(0)]
                public System.Runtime.InteropServices.ComTypes.FILETIME m_FileTime;
                [FieldOffset(0)]
                public int m_Int;
                [FieldOffset(0)]
                public IntPtr m_StringPtr;
            }
        }
        #endregion
    
        #region WinInet enums
        //
        // options manifests for Internet{Query|Set}Option
        //
        public enum InternetOption : uint
        {
            INTERNET_OPTION_PER_CONNECTION_OPTION = 75
        }
    
        //
        // Options used in INTERNET_PER_CONN_OPTON struct
        //
        public enum PerConnOption
        {
            INTERNET_PER_CONN_FLAGS = 1, // Sets or retrieves the connection type. The Value member will contain one or more of the values from PerConnFlags 
            INTERNET_PER_CONN_PROXY_SERVER = 2, // Sets or retrieves a string containing the proxy servers.  
            INTERNET_PER_CONN_PROXY_BYPASS = 3, // Sets or retrieves a string containing the URLs that do not use the proxy server.  
            INTERNET_PER_CONN_AUTOCONFIG_URL = 4//, // Sets or retrieves a string containing the URL to the automatic configuration script.  
    
        }
    
        //
        // PER_CONN_FLAGS
        //
        [Flags]
        public enum PerConnFlags
        {
            PROXY_TYPE_DIRECT = 0x00000001,  // direct to net
            PROXY_TYPE_PROXY = 0x00000002,  // via named proxy
            PROXY_TYPE_AUTO_PROXY_URL = 0x00000004,  // autoproxy URL
            PROXY_TYPE_AUTO_DETECT = 0x00000008   // use autoproxy detection
        }
        #endregion
    
        internal static class NativeMethods
        {
            [DllImport("WinInet.dll", SetLastError = true, CharSet = CharSet.Auto)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool InternetSetOption(IntPtr hInternet, InternetOption dwOption, IntPtr lpBuffer, int dwBufferLength);
        }
    }

      UnsetProxy方法为取消代理设置,SetProxy(string strProxy, string exceptions)方法为设置指定代理。

      以下是我做的一个可以动态修改代理的Winform程序,备忘下载

  • 相关阅读:
    数据--第28课
    数据--第27课
    数据--第26课
    数据--第25课
    数据--第23课
    数据--第24课
    数据--第22课
    数据--第21课-递归课后练习
    lambda表达式
    数组和链表
  • 原文地址:https://www.cnblogs.com/skybreak/p/3554229.html
Copyright © 2011-2022 走看看