使用Watin更改IE实例的代理设置

时间:2014-08-03 19:09:32

标签: c# asp.net unit-testing watin

我知道我可以更改计算机全局代理设置Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings,以影响使用Watin创建的IE实例。

但有没有办法拦截IE浏览器发出的请求并通过代理运行它们?我的目标是运行IE的多个实例,每个实例都有自己的代理,这对于我上面的当前解决方案是不可能的。

6 个答案:

答案 0 :(得分:4)

WatiN IE创建多个 ProcessID (单个实例IE创建多个进程ID)。为了通过使用 Fiddler Core 覆盖WatiN的代理设置,我们需要获取由WatiN IE创建的所有子进程ID。帮助程序类可以在PInvoke: Getting all child handles of window – Svett Ralchev类找到。然后我们检查 BeforeRequest 事件中的所有进程ID,并等待watin进程ID覆盖代理设置。

    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];
        }
    } 

可以在此处下载测试应用 http://www.rentanadviser.com/downloads/WatiN-2.1.0.1196.zip

使用下面的不同匿名代理测试结果。 (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

示例代码:

    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];
        }
    }    

答案 1 :(得分:3)

我创建了一个名为Process Proxifier的应用,它使用FiddlerCore动态地向Windows应用程序添加代理设置。您可以在此处找到完整的源代码:https://processproxifier.codeplex.com/

另外我应该提一下,这个解决方案仅限于具有系统默认“CERN”代理设置的目标进程(指向Fiddler / FiddlerCore)。

答案 2 :(得分:2)

使用IE甚至WebBrowser都不可能做到这一点(它只是IE的一个实例)。

但您可以操纵WebBrowser行为以实现所需的功能。

可以编写自定义WebBrowser,它通过发送包含不同代理的自定义WebRequest来获取数据。

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

答案 3 :(得分:2)

我知道您正在寻找an alternative solution without using the computers global proxy setting,但我想在此处添加此内容,以便其他没有这种约束的人了解它。

解决方案就在您的问题上 - The Windows Registry

在运行时全局更改代理设置很简单,您需要使用Microsoft.Win32.Registry命名空间中的Microsoft.Win32类更改您感兴趣的注册表项。

您可以在此处找到MSDN文档:http://msdn.microsoft.com/en-us/library/microsoft.win32.registry(v=vs.110).aspx

请参阅下面的示例,了解如何执行此操作。

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

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

现在要更改框中的代理设置,您需要更改或创建正确的代理注册表项,您可以在以下位置找到所有可用的密钥:

以下是您需要设置的一些按键。每个版本的IE都有自己的密钥,但下面的密码与所有浏览器相同。

<强> 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

特定于用户

请注意这些是当前用户注册表项,因此您可能需要在Windows标识的上下文中设置它们。另外,查看这些键值的最简单方法是在“Internet设置”对话框中应用代理更改,并在RegEdit.exe上进行检查。

自动创建用户

这是您的优惠,因为您可以使用您不需要更改自己的代理设置的设置在本地Windows帐户上运行watin进程。

然后,您可以让一个名为WatinUser的用户设置代理设置,您可以使用System.DirectoryServices.AccountManagement Namespace类自动创建此用户。

答案 4 :(得分:2)

Proxifier等产品可让您根据应用程序名称,IP地址,主机名和端口号设置规则,以便将流量路由到不同的代理。这不允许您为多个IE进程使用不同的代理,但如果这些进程访问不同的URL,您可以通过单独的代理服务器路由流量。 Proxifier使用WinSocks堆栈,类似于许多防病毒软件使用的堆栈,它对应用程序层是透明的。

答案 5 :(得分:1)

另一个建议是编写自己的Web请求拦截器/代理服务器,它将从请求的URL获取代理服务器信息,并将规范化的URL转发到真正的代理服务器。 例如从watin你启动URL“someurl?ProxyServer = 10.10.10.12”现在这将被你自己的代理服务器拦截,它将使用代理服务器参数重定向请求的URL,即“someurl”到10.10.10.12您的代理服务器实现可以设置运行时的代理详细信息,并使用动态代理从服务器获取结果。

我希望它有道理。

相关问题