ProxySwitch

HZe I use a Windows notebook at work and at home. At work, there is Internet access through a proxy server while at home I can access Internet directly without proxy through a DSL router.

DHCP works fine to get the IP-addresses without reconfiguration, but every time I switched the networks I had to enable/disable the proxy settings.

I would assume, that a proxy server is a configuration, that depends on the network, like e.g. the DNS configuration or how to set the IP address. However, I did not find a way to include the proxy setting depending on the network environment on Windows.

So I came up with this little script, which does the same based on the current network connection. I added it to my windows AutoStart group and now I'm fine.


HZe - 11-OCT-2004: now it also supports Mozilla Firefox


HZe - 18-DEC-2005: now also supports a silent mode and optionally a start of a command after the proxy setting was done. On my Windows machine I use this as short cut to start FireFox:

   proxyswitch.tcl -silent 1 -exec "c:\Programme\Mozilla Firefox\firefox.exe" "DNS-Suffix:[ \t]*atwork.com" "proxyhost:3128"

So, every time I start FireFox using this short cut, it checks in which network the machine is connected and sets the proxy accordingly.


HZe - 09-MAR-2008: I've added some features:

  • setting of start page for Internet Explorer (when this is overwritten by some network login, this will allow you to set it to your preferred page
  • instead of providing command line parameters for multiple network environments, they can be supplied in a file. On Windows the command line may not be long enough to supply all necessary parameters, e.g. if you want to configure more than two networks
  • if silent mode is not selected, the window informing about the used proxy server is closed automatically after 3 seconds, if not closed by pressing the button. Please note, that those 3 seconds do not delay the start of the browser, it is started before in background.

HZe - 26-MAR-2010: to use the tool without having Tcl/Tk installed, here's a ready-to-use executable for Windows: [L1 ]


HZe - 13-NOV-2010: updated the script to also deal with Google Chrome. Chrome is using the Proxy settings from Windows Internet Explorer, however it was not enough to just do the settings that work for Internet Explorer. So, in case of Chrome I also add a command line switch to set the proxy for Chrome.


    # Switch to enable/disable Proxy depending on Company net or HOME net
    # Tested on Windows XP

    proc usage {} {
        wm protocol . WM_DELETE_WINDOW exit
        frame .f
        text .f.info -yscrollcommand [list .f.sb set] -width 80 -height 15
        scrollbar .f.sb -orient vert -command [list .f.info yview]
        button .b -text "      OK      " -command {set ::continue 1}
        pack .f.sb -side right -fill y
        pack .f.info -side right -fill both -expand 1
        pack .f -fill both -expand 1 -padx 5 -pady 5
        pack .b -pady 5

        .f.info insert end {ProxySwitch

        sets the proxy in your Internet Explorer depending the network connection

    Author:
        Holger Zeinert (holger DOT zeinert AT gmx DOT de)

    usage:
        tclsh proxyswitch.tcl [-silent 0|1] [-exec <cmd>] <re-expr> <proxyhost:port> ...
        proxyswitch.exe [-silent 0|1] [-exec <cmd>] <re-expr> <proxyhost:port> ...

        tclsh proxyswitch.tcl <filename-for-args>
        proxyswitch.exe <filename-for-args>


    Description:
        Depending on the output of ipconfig, the setting of the Proxy is changed. This
        is done in the registry for Internet Explorer and in the file prefs.js for
        Mozilla Firefox

        To do so, the output of ipconfig is matched against the regular expressions. The first
        fit determines the proxy host and port to be used. Since the whole output of ipconfig
        is base for regexp, you can make a decision on IP-Address, DNS suffix or whatever.

        If no match fits, the default is to disable the proxy.

        -silent 0|1:
            if set to 1, there will be no message box used to report the action
        -exec <cmd>:
            call a command after the setting was made
        -startpage <url>:
            set the start page for Internet Explorer

        If the command line gets too long, alternatively the arguments can be stored
        in a file and only the filename has to be passed as single argument:

        tclsh proxyswitch.tcl <filename-for-args>
        proxyswitch.exe <filename-for-args>

        The <filename-for-args> includes the arguments, they can be spread over serveral
        lines. However, the arguments have to be a valid tcl list, i.e. it's either
            tclsh proxyswitch.tcl -exec "C:\Program Files\my Browser\prog.exe"
        or
            tclsh proxyswitch.tcl "C:\Documents and Settings\me\config.rc"
        C:\Documents and Settings\me\config.rc:
            -exec {C:\Program Files\my Browser\prog.exe}


    Examples:
        tclsh proxyswitch.tcl ":[ \t]*10.2." "gate:3128"
        proxyswitch.exe ":[ \t]*192.168." "gate:8888" "DNS-Suffix: home" "world.home.de:3200"

    Appendix:
        An output of ipconfig looks e.g. like this:

            Windows-IP-Konfiguration

            Ethernetadapter WLAN-Verbindung :

                    Verbindungsspezifisches DNS-Suffix: home
                    IP-Adresse. . . . . . . . . . . . : 192.168.1.2
                    Subnetzmaske. . . . . . . . . . . : 255.255.255.0
                    Standardgateway . . . . . . . . . : 192.168.1.1
        }
        after 500 {
            if {[catch {
                foreach {xs ys} [split [wm geometry .] x+] {
                    # lassign simulator
                }
                wm minsize . $xs $ys
            } msg]} {
                tk_messageBox -icon error -message $msg
            }
        }
        vwait ::continue
    }


    package require registry


    if {$argv == ""} {
        usage
        exit
    }
    if {[llength $argv] == 1} {
        # only a configuration file was given with the argv vector
        set cfgname [lindex $argv 0]
        if {[catch {
            set fp [open $cfgname]
            set argv [list]
            while {![eof $fp]} {
                gets $fp line
                foreach v $line {
                    lappend argv $v
                }
            }
            close $fp
        } errmsg]} {
            tk_messageBox -message "Could not read file $cfgname. \n\n$errmsg\n\nIgnoring file configuration."    
        }
    }

    if {[catch {set ipconfig [exec ipconfig]}]} {
        tk_messageBox -message "could not start ipconfig! Not running Windows?"
        exit
    }

    set server "off"
    set silent 0
    set cmd [list]
    set startpage ""
    foreach {key value} $argv {
        # options
        switch -- $key {
            -silent {
                set silent $value
            }
            -exec {
                set cmd [list $value]
            }
            -startpage {
                set startpage $value
            }
            default {
                if {[regexp $key $ipconfig]} {
                    set server $value
                    break
                }
            }
        }
    }

    if {!$silent} {
        # show activity
        label .info1 -text "Updating Firefox/Internet Explorer Configuration..."
        label .info2
        button .b -text "Exit" -command exit
        pack .info1 .info2 .b -fill x -expand 1
        update
    }

    # depending on proxy, set override proxy for local addresses
    if {$server == "off"} {
        set server ""
        set override ""
        set switch 0
    } else {
        set override <local>
        set switch 1
    }

    #---------------------------------------------------------------------
    # Chrome
    #   it seems to be not sufficient to set the IE Internet settings, while Chrome
    #   is using them.
    #   So we will give it another hint...
    if { [string match -nocase "*chrome*" $cmd] } {
        lappend cmd "--proxy-server=$server"
    }

    #---------------------------------------------------------------------
    # Internet Explorer 6
    #

    # set the entries in the registry

    # ToDo: to also set this value for the 64 bit browser, I have to use RegEnableReflectionKey()
    #       to make Windows copy the value also to the 64bit version of the Registry                             
    set keyName {HKEY_CURRENT_USER\SOFTWARE\microsoft\windows\currentversion\internet settings}
    registry set $keyName "ProxyEnable" $switch dword
    registry set $keyName "ProxyServer" $server
    catch {
        # in case current user is not Admin...
        set keyName {HKEY_LOCAL_MACHINE\SOFTWARE\microsoft\windows\currentversion\internet settings}
        registry set $keyName "ProxyEnable" $switch dword
        registry set $keyName "ProxyServer" $server
    }
    # set keyName {HKEY_LOCAL_MACHINE\SOFTWARE\Altiris\Communications}
    # registry set $keyName "Proxy Server" [lindex [split $server ":"] 0]
    # registry set $keyName "Proxy Port" [lindex [split $server ":"] 1] dword

    #registry set $keyName "ProxyOverride" $override
    if {$startpage != ""} {
        set keyName {HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main}
        registry set $keyName "Start Page" $startpage
    }
    if {!$silent} {
        if {$switch} {
            .info2 configure -text "Proxy set to $server!"
        } else {
            .info2 configure -text "Proxy disabled!"
        }
        update
    }

    #---------------------------------------------------------------------
    # FireFox 0.9.3, 1.0PR, ... 3.6
    #

    set tmp [split $server ":"]
    set host [lindex $tmp 0]
    set port [lindex $tmp 1]

    foreach pref [glob -nocomplain [file join $env(APPDATA) Mozilla Firefox Profiles * prefs.js]] {
        set in [open $pref r]
        set out [open $pref.tmp w]
        while {![eof $in]} {
            gets $in line
            if {![regexp {user_pref\("network\.proxy\.(http|type).*",.*} $line]} {
                puts $out $line
            }
        }
        # TODO: deal with other proxy settings as well.
        if {$switch} {
            puts $out "user_pref(\"network.proxy.http\", \"$host\");"
            puts $out "user_pref(\"network.proxy.http_port\", $port);"
            puts $out "user_pref(\"network.proxy.type\", 1);"
        }
        close $in
        close $out
        file rename -force $pref.tmp $pref
    }

    # start a command after the configuration setting
    if {$cmd != ""} {
        exec {*}$cmd &
    }

    if {! $silent } {
        after 3000 exit
    } else {
        exit
    }