views:

135

answers:

3

I am a hobbyist programmer, and I am attempting to write an application that automatically changes the proxy server based upon what network connection is active. In this application, the user can also manually click a server in the notifyIcon context menu and call the function to switch the server. My problem is the following: The application changes the proxy server the first time the function is called, but will not work after that. I have put debug statements in to make sure the correct proxy server is being passed to that function (and it is indeed correct), but the registry entries never get changed after the first time. What am I doing wrong?

Here is my Proxy Class:

class Proxy
{
    [DllImport("wininet.dll")]
    public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength);
    public const int INTERNET_OPTION_SETTINGS_CHANGED = 39;
    public const int INTERNET_OPTION_REFRESH = 37;
    static bool settingsReturn, refreshReturn;

    public void SetProxy(ProxyList proxy)
    {
        RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
        registry.SetValue("ProxyEnable", 1);
        registry.SetValue("ProxyServer", proxy.server + ":" + proxy.port);
        registry.Close();

        // These lines implement the Interface in the beginning of program 
        // They cause the OS to refresh the settings, causing IP to realy update
        settingsReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);
        refreshReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);
    }


}

And here is how I call the function from the context menu:

void Form1_Click(object sender, EventArgs e)
    {
        Proxy proxyServer = new Proxy();
        ToolStripMenuItem item = (ToolStripMenuItem)sender;
        proxyServer.SetProxy(XML.proxy[(int)item.Tag]);
        proxyServer = null;
        notifyIcon1.BalloonTipText = XML.proxy[(int)item.Tag].name + " is now your Active Proxy";
        notifyIcon1.ShowBalloonTip(1);
    }

Any help would be greatly appreciated.

A: 

i think you'd better do a plug-in for your browser instead of changing the registry directly.

Benny
What about non-browser applications, like email clients?
Jeremy Seghi
+1  A: 

From Microsoft's Knowledge Base: How to programmatically query and set proxy settings under Internet Explorer

Note INTERNET_OPTION_PER_CONNECTION_OPTION causes the settings to be changed on a system-wide basis when a NULL handle is used. To correctly reflect global proxy settings, you must call the InternetSetOption function with the INTERNET_OPTION_REFRESH option flag.

This is from MSDN

INTERNET_OPTION_PER_CONNECTION_OPTION
75
Sets or retrieves an INTERNET_PER_CONN_OPTION_LIST structure that specifies a list of options for a particular connection. This is used by InternetQueryOption and InternetSetOption. This option is only valid in Internet Explorer 5 and later.

Read about the INTERNET_PER_CONN_OPTION_LIST structure.

Note: the value for the INTERNET_PER_CONN_PROXY_SERVER flag is 2.

Wolf
Nice and detailed answer.
nbolton
Thanks. Adding the flag value will hopefully be helpful to a C# programmer with no quick reference to the Windows API, and it is not defined on MSDN. I wish I had thought about making a program to do just that when I was in college. I had to manually switch between 3 different proxies.
Wolf
A: 

RegistryKey class is disposable. Maybe it is being cached or something, try disposing it in addition of closing it.

Hogan