Retrieve Internet explorer proxy settings from the registry I just re-wrote a library to easily retrieve the proxy settings of Internet Explorer (self answered SO question: https://stackoverflow.com/q/41764614/3207406).

Git repository

GoDoc (with an example)

package ieproxy

import (
    "os"
    "strings"
    "sync"

    "golang.org/x/sys/windows/registry"
)

// StaticProxyConf containes the Windows configuration for static proxy
type StaticProxyConf struct {
    // Is the proxy active?
    Active bool
    // Proxy address for each scheme (http, https)
    // "" (empty string) is the fallback proxy
    Protocols map[string]string
    // Addresses not to be browsed via the proxy (comma-separated, like linux)
    NoProxy string
}

// AutomaticProxyConf contains the Windows configuration for automatic proxy
type AutomaticProxyConf struct {
    URL string // url of the .pac file
}

// WindowsProxyConf gathers the Windows configuration for proxy
type WindowsProxyConf struct {
    Static    StaticProxyConf    // static configuration
    Automatic AutomaticProxyConf // automatic configuration
}


type regeditValues struct {
    ProxyServer   string
    ProxyOverride string
    ProxyEnable   uint64
    AutoConfigURL string
}

var once sync.Once
var windowsProxyConf WindowsProxyConf

// GetConf retrieves the proxy configuration from the Windows Regedit
func getConf() WindowsProxyConf {
    once.Do(parseRegedit)
    return windowsProxyConf
}

// OverrideEnvWithStaticProxy writes new values to the
// http_proxy, https_proxy and no_proxy environment variables.
// The values are taken from the Windows Regedit (should be called in init() function)
func overrideEnvWithStaticProxy() {
    conf := getConf()
    if conf.Static.Active {
        for _, scheme := range []string{"http", "https"} {
            url, ok := conf.Static.Protocols[scheme]
            if !ok {
                url, ok = conf.Static.Protocols[""] // fallback conf
            }
            if ok {
                os.Setenv(scheme+"_proxy", url)
            }
        }
        if conf.Static.NoProxy != "" {
            os.Setenv("no_proxy", conf.Static.NoProxy)
        }
    }
}

func parseRegedit() {
    regedit, _ := readRegedit()

    protocol := make(map[string]string)
    for _, s := range strings.Split(regedit.ProxyServer, ";") {
        if s == "" {
            continue
        }
        pair := strings.SplitN(s, "=", 2)
        if len(pair) &gt; 1 {
            protocol[pair[0]] = pair[1]
        } else {
            protocol[""] = pair[0]
        }
    }

    windowsProxyConf.Static = StaticProxyConf{
        Active:    regedit.ProxyEnable &gt; 0,
        Protocols: protocol,
        NoProxy:   strings.Replace(regedit.ProxyOverride, ";", ",", -1), // to match linux style
    }
    windowsProxyConf.Automatic = AutomaticProxyConf{
        URL: regedit.AutoConfigURL,
    }
}

func readRegedit() (values regeditValues, err error) {
    k, err := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Internet Settings`, registry.QUERY_VALUE)
    if err != nil {
        return
    }
    defer k.Close()

    values.ProxyServer, _, err = k.GetStringValue("ProxyServer")
    if err != nil &amp;&amp; err != registry.ErrNotExist {
        return
    }
    values.ProxyOverride, _, err = k.GetStringValue("ProxyOverride")
    if err != nil &amp;&amp; err != registry.ErrNotExist {
        return
    }

    values.ProxyEnable, _, err = k.GetIntegerValue("ProxyEnable")
    if err != nil &amp;&amp; err != registry.ErrNotExist {
        return
    }

    values.AutoConfigURL, _, err = k.GetStringValue("AutoConfigURL")
    if err != nil &amp;&amp; err != registry.ErrNotExist {
        return
    }
    err = nil
    return
}


I'm interested to know if the "go-style" can be improved and any other suggestions!
As is, the (my) code is really hard to test (needs actual registry modifications or env variable edition).

To ease the testing, one could change some functions:

func overrideEnvWithStaticProxy(conf ProxyConf, setenv envSetter) {
    ...
}
type envSetter func(string, string) error

func parseRegedit(regedit regeditValues) ProxyConf {
   ...
}


With this change overrideEnvWithStaticProxy and parseRegedit become self contained and can be easily tested!

This incurs a minor rewrite of getConf (which does only some plumbing):

func getConf() ProxyConf {
    once.Do(writeConf)
    return windowsProxyConf
}

func writeConf() {
    regedit, _ := readRegedit()
    windowsProxyConf = parseRegedit(regedit)
}