Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change proxy setting for IE instance using Watin

I know that I can change the computers global proxy setting, Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings, to affect IE instances created using Watin.

But is there any way to intercept requests made by the IE browsers and run them through a proxy? My goal is to run multiple instances of IE, each with its own proxy, which isn't possible with my current solution above.

like image 330
Johan Avatar asked Aug 03 '14 19:08

Johan


4 Answers

WatiN IE creates multiple ProcessIDs (single instance IE creates multiple process ids). in order to overwrite proxy settings just for WatiN by using Fiddler Core we need to get all child process ids which are created by WatiN IE. Helper class can be found here PInvoke: Getting all child handles of window – Svett Ralchev class. And then we check all process ids inside the BeforeRequest event and wait for watin process id to overwrite proxy settings.

    private void FiddlerApplication_BeforeRequest(Session sess)
    {
        //Debug.WriteLine("FiddlerApplication_BeforeRequest: " + sess.LocalProcessID.ToString());
        if (WatinIEprocessHolder.ContainsKey(sess.LocalProcessID))
        {                
            //see http://stackoverflow.com/questions/14284256/how-to-manually-set-upstream-proxy-for-fiddler-core
            sess["X-OverrideGateway"] = WatinIEprocessHolder[sess.LocalProcessID];
        }
    } 

Working Test Application can be downloaded here http://www.rentanadviser.com/downloads/WatiN-2.1.0.1196.zip

Test results with different anonymous proxy below. (ipaddress=browser.Text)

Process Ids:3852,7852,, Your IP address: 119.46.110.17, Proxy:119.46.110.17:8080
Process Ids:2508,6948,, Your IP address: 178.21.112.27, Proxy:178.21.112.27:3128
Process Ids:1348,1368,, Your IP address: 122.96.59.107, Proxy:122.96.59.107:83
Process Ids:7152,5104,, Your IP address: 136.0.16.217, Proxy:136.0.16.217:3127
Process Ids:4128,3480,, Your IP address: 198.52.199.152, Proxy:198.52.199.152:7808
Process Ids:2036,7844,, Your IP address: 122.96.59.107, Proxy:122.96.59.107:82

Sample code:

    private void this_FormClosing(object sender, FormClosingEventArgs e)
    {
        StopFiddler();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        this.FormClosing += this_FormClosing;

        ProxyHolder = new List<string>();
        ProxyHolder.Add("119.46.110.17:8080");
        ProxyHolder.Add("178.21.112.27:3128");
        ProxyHolder.Add("122.96.59.107:83");
        ProxyHolder.Add("136.0.16.217:3127");
        ProxyHolder.Add("198.52.199.152:7808");
        ProxyHolder.Add("122.96.59.107:82");

        StartFiddler();
        System.Threading.Thread.Sleep(500);

        for (var i = 0; i < ProxyHolder.Count; i++)
        {
            WhatIsMyIpThroughProxy(ProxyHolder[i]);
            Application.DoEvents();
            System.Threading.Thread.Sleep(500);
        }
        //WhatIsMyIpThroughProxy();
    }

    private Dictionary<int, string> WatinIEprocessHolder = new Dictionary<int, string>();
    private List<string> ProxyHolder = null;

    public void WhatIsMyIpThroughProxy(string ProxyIPandPort)
    {

        using (var browser = new IE(true))// we should not navigate now. Because we need process ids.
        {
            WindowHandleInfo ChildHandles = new WindowHandleInfo(browser.hWnd);
            foreach (var cHandle in ChildHandles.GetAllChildHandles())
            {
                int pid = new WatiN.Core.Native.Windows.Window(cHandle).ProcessID;
                if (WatinIEprocessHolder.ContainsKey(pid) == false)
                    WatinIEprocessHolder.Add(pid, ProxyIPandPort);
            }

            System.Text.StringBuilder processIDs = new System.Text.StringBuilder();
            foreach (var k in WatinIEprocessHolder.Keys)
            {
                processIDs.Append(k.ToString() + ",");
                //Debug.WriteLine(string.Format("{0}:{1}", k, WatinIEprocessHolder[k]));
            }

            //we got the process ids above. Navigate now.
            browser.GoTo("http://www.rentanadviser.com/en/common/tools.ashx?action=whatismyip");
            browser.WaitForComplete();

            WatinIEprocessHolder.Clear();

            System.Net.IPAddress ip;
            if (System.Net.IPAddress.TryParse(browser.Text, out ip))
            {
                Debug.WriteLine(string.Format("Process Ids:{0}, Your IP address: {1}, Proxy:{2}", processIDs.ToString(), browser.Text, ProxyIPandPort));
            }
            else
            {
                Debug.WriteLine(string.Format("Process Ids:{0}, Your IP address: {1}, Proxy:{2}", processIDs.ToString(), "Failed", ProxyIPandPort));
            }
        }
    }


    private void StartFiddler()
    {
        FiddlerApplication.BeforeRequest += FiddlerApplication_BeforeRequest;
        FiddlerApplication.Startup(8888, true, true, true);
    }

    private void StopFiddler()
    {
        FiddlerApplication.BeforeRequest -= FiddlerApplication_BeforeRequest;
        if (FiddlerApplication.IsStarted())
        {
            FiddlerApplication.Shutdown();
        }
    }


    private void FiddlerApplication_BeforeRequest(Session sess)
    {
        //Debug.WriteLine("FiddlerApplication_BeforeRequest: " + sess.LocalProcessID.ToString());
        if (WatinIEprocessHolder.ContainsKey(sess.LocalProcessID))
        {                
            //see http://stackoverflow.com/questions/14284256/how-to-manually-set-upstream-proxy-for-fiddler-core
            sess["X-OverrideGateway"] = WatinIEprocessHolder[sess.LocalProcessID];
        }
    }    
like image 116
khan Avatar answered Sep 30 '22 12:09

khan


I've created an app called Process Proxifier which uses FiddlerCore to add proxy settings to the Windows applications dynamically. You can find its full source code here: https://processproxifier.codeplex.com/

Also I should mention that this solution is limited to target processes with system's default "CERN" proxy setting (which is pointed at Fiddler/FiddlerCore).

like image 29
VahidN Avatar answered Sep 30 '22 13:09

VahidN


It's not possible to do that with IE or even with WebBrowser (it's just an instance of IE).

But you can manipute WebBrowser behavior to achieve your desired feature.

It's possible to write your custom WebBrowser which fetched data by sending your custom WebRequest that contain your different proxy.

How to load web browser with web response

HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("http://example.com");
webRequest.Proxy = new WebProxy(host, port);

HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();
Stream receiveStream = response.GetResponseStream();

WebBrowser webBrowser = new WebBrowser();
webBrowser.DocumentStream = receiveStream;   

WebRequest.Proxy

like image 29
Hiệp Lê Avatar answered Sep 30 '22 13:09

Hiệp Lê


I know you are looking for an alternative solution without using the computers global proxy setting but I thought of adding this here so others who don't have this constraint know about it.

The solution was on your question - The Windows Registry.

It is simple to change the proxy settings globally at runtime, you need to change the registry keys you are interested in using the Microsoft.Win32.Registry class in the Microsoft.Win32 namespace.

You can find MSDN documentation for this here: http://msdn.microsoft.com/en-us/library/microsoft.win32.registry(v=vs.110).aspx

See below an example of how to do this.

RegistryKey myKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Your key", true);

myKey.SetValue("My String Value", "Test Value", RegistryValueKind.String);

Now to change proxy settings on the box you need to change or create the right proxy registry keys you can find all the available keys at:

  • MSDN Documentation - 2.2.1.10 Internet Settings.

Below is a few of the keys you need to set. Each version of IE has their own keys but the ones below are identical to all browsers.

UseProxyServer REG_DWORD

  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyEnable

ProxyServerAndPort REG_DWORD

  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer

ProxyOverride REG_SZ

  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyOverride

HTTP1_1ThroughProxy REG_DWORD

  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\HTTP1_1ThroughProxy

User Specific

Please bear in mind these are Current user registry entries so you may need to set them in the context of the windows identity. Also the simplest way to see what should be the values for these keys is to apply the proxy changes on the Internet Settings dialog and check them on RegEdit.exe.

Create user automatically

This is your saving grace here because you can run your process for watin on a local windows account with the settings that way you dont need to change your own proxy settings.

You can then have one user called WatinUser that the proxy settings are set against you can automate the creation of this user using the System.DirectoryServices.AccountManagement Namespace classses.

  • See examples here at SO: create local user account
like image 22
dmportella Avatar answered Sep 30 '22 13:09

dmportella