我的目标是通过C#代码设置和取消网络代理。
从网上找了段代码,写一个小程序来测试一下,点击form上的一个按钮设置代理,一个按钮取消代理,代码如下
按钮的事件中除了修改注册表以外还调用了,wininet.dll中的InternetSetOption,用于即使IE没有关闭也能更新当前打开的IE中的代理设置。
但是现在遇到的问题是,启动这个程序,第一下乌云是点击设置代理还是取消代理都正确,但是在不关闭这个程序的情况下,再去点击另外一个按钮,代理没有改变。Debug之后发现,是由于InternetSetOption这个函数导致的,假设我先点击设置代理的按钮,注册表修改成功,当前打开的IE代理设置修改也成功,但是再点击取消代理时,未执行InternetSetOption函数时修改注册表成功,再执行InternetSetOption函数又把注册表修改会设置代理的值了。
也就是会所当程序在同一次运行状态中,调用InternetSetOption刷新只会按照第一次修改注册表的值进行刷新。请教各位大牛,有没有了解InternetSetOption这个函数的,或者遇到过这样的问题,有什么好方法可以解决这个问题
全部代码都在这,有兴趣的可以试试,是不是跟我一个现象。我的电脑是Win7 + vs2010 sp1public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        #region 用于刷新IE代理设置
        [DllImport("wininet.dll", SetLastError = true)]
        private static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lPBuffer, int lpdwBufferLength);        private const int INTERNET_OPTION_REFRESH = 0x000025;
        private const int INTERNET_OPTION_SETTINGS_CHANGED = 0x000027;
        #endregion        //设置代理
        private void enableProxyButton_Click(object sender, EventArgs e)
        {
            //设置注册表相应键值
            RegistryKey key = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
            key.SetValue("ProxyOverride", "10.2.1.*;<local>");
            key.SetValue("ProxyServer", "proxy.com:8080");
            key.SetValue("ProxyEnable", 1);
            key.Close();
            //刷新
            InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);
            InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);
        }
        //取消代理
        private void disableProxyButton_Click(object sender, EventArgs e)
        {
            //设置注册表相应键值
            RegistryKey key = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
            key.SetValue("ProxyEnable", 0);
            key.Close();
            //刷新
            InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);
            InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);
        }
    }

解决方案 »

  1.   

      using (RegistryKey key = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true))
                {
                    key.SetValue("ProxyOverride", "10.2.1.*;<local>");
                    key.SetValue("ProxyServer", "proxy.com:8080");
                    key.SetValue("ProxyEnable", 1);
                    key.Flush();
                    key.Close();
                }
       using (RegistryKey key = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true))
                {
                    key.SetValue("ProxyEnable", 0);
                    key.Flush();
                    key.Close();
                }这样改呢
      

  2.   

    TO:JulioHuang 我通过调试观察到,实际上在keyc.close()这句代码的时候一切都是正常的,就是在InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);这句一调用,注册表里的值就又变回去了。
      

  3.   

    To:jshi123,你尝试运行起来程序之后,点击设置代理,再点击取消代理,看看取消代理是否可用。
    我这里每次运行起来第一个操作都可用,但是操作完之后再执行另外一个操作就会在InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0)的时候会刷新回第一个操作后结果。InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0)这个函数里面做了什么操作?
      

  4.   

    To:chennjnu 一起吧。呵呵,你要是想明白也麻烦通知我一下。多谢!
      

  5.   

    两个按钮分别来回点击20次以上均正常。我觉得还是我们的配置有不同,我的是:
    win7 旗舰版 32位 service pack 1
    Visual Studio 2010 Ultimate 10.0.40219.1 SP1Rel另外我用的杀毒软件是Norton360,你看看和你有什么不同,都一样的话,我们再看看还有其它什么区别
      

  6.   

    bResult = InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);    //通知注册表中代理改变,下次连接时启动代理
    bResult = InternetSetOption(NULL ,INTERNET_OPTION_REFRESH , NULL, NULL);    //从注册表中读入代理
    执行这两行代码以后,注册表里的值就又变回去了。
      

  7.   

    真的跟Win7的版本有关系,我下午把win7升级到sp1就好了,VS的版本跟jshi123的一样的,多谢jshi123
    不过有没有其他方式来解决呢,难道这个程序写出来之后在很大一部分Win7的机器上都会有问题?我原先跟chenjnu一样,以运行InternetSetOption就把注册表里的值改回去了,好像InternetSetOption里面有个缓存似的,我重新运行一下这个程序就可以改一次。明天派分,再看看今天晚上有没有人能够分析一下原因。
      

  8.   

    网上也没找到很明确的资料,但是有不少人都有同样的问题。这里有个解决方案是说不要用注册表,直接用WinInet API来改代理设置:
    http://stackoverflow.com/questions/1781616/c-wininet-change-proxy-settings-windows-7另外一个方法是说开另外一个进程去改设置:
    http://social.msdn.microsoft.com/Forums/zh-CN/2212/thread/450afb49-bd95-468a-8cc6-513a491eb3c9因为没有环境,两个方法我都没试过,不过最简单的应该是:可行的话,设置完后提示用户重启程序,或者判断OS版本,win7的话提示用户装sp
      

  9.   

    网上也没找到很明确的资料,但是有不少人都有同样的问题。这里有个解决方案是说不要用注册表,直接用WinInet API来改代理设置:
    http://stackoverflow.com/questions/1781616/c-wininet-change-proxy-settings-windows-7