CefSharp 3在运行时设置代理

时间:2016-03-18 22:53:38

标签: c# c++ proxy chromium-embedded cefsharp

我下载了CEF(chromuim嵌入式框架)二进制分发(cefclient& cefsimple)c ++示例,并且实现了cefclient可以在运行时更改代理设置。

这样做的关键是抓住RequestContext并调用函数SetPreference。

在CefClient上一切正常。

但是在CefSharp上调用SetPreference总是返回false,并且HasPreference对于首选项名称“proxy”也返回false。

4 个答案:

答案 0 :(得分:6)

感谢amaitland主动强制更改请求上下文优先级的正确方法是在CEF UIThread上运行代码,如下所示:

    Cef.UIThreadTaskFactory.StartNew(delegate {
        var rc = this.browser.GetBrowser().GetHost().RequestContext;
        var v = new Dictionary<string, object>();
        v["mode"] = "fixed_servers";
        v["server"] = "scheme://host:port";
        string error;
        bool success = rc.SetPreference("proxy", v, out error);
        //success=true,error=""
    });

答案 1 :(得分:2)

如果有人需要任何其他灵魂,我找到了这个解决方案。

Cef.UIThreadTaskFactory.StartNew(delegate
        {
            string ip = "ip or adress";
            string port = "port";
            var rc = this.browser.GetBrowser().GetHost().RequestContext;
            var dict = new Dictionary<string, object>();
            dict.Add("mode", "fixed_servers");
            dict.Add("server", "" + ip + ":" + port + "");
            string error;
            bool success = rc.SetPreference("proxy", dict, out error);

        });

答案 2 :(得分:1)

我下载了CefSharp.WinForms 65.0.0并制作了类,可以帮助您开始使用代理:

public class ChromeTest
{
    public static ChromiumWebBrowser Create(WebProxy proxy = null, Action<ChromiumWebBrowser> onInited = null)
    {
       var result = default(ChromiumWebBrowser);
        var settings = new CefSettings();
        result = new ChromiumWebBrowser("about:blank");
        if (proxy != null)
            result.RequestHandler = new _requestHandler(proxy?.Credentials as NetworkCredential);

        result.IsBrowserInitializedChanged += (s, e) =>
        {
            if (!e.IsBrowserInitialized)
                return;

            var br = (ChromiumWebBrowser)s;
            if (proxy != null)
            {
                var v = new Dictionary<string, object>
                {
                    ["mode"] = "fixed_servers",
                    ["server"] = $"{proxy.Address.Scheme}://{proxy.Address.Host}:{proxy.Address.Port}"
                };
                if (!br.GetBrowser().GetHost().RequestContext.SetPreference("proxy", v, out string error))
                    MessageBox.Show(error);
            }

            onInited?.Invoke(br);
        };

        return result;
    }

    private class _requestHandler : DefaultRequestHandler
    {
        private NetworkCredential _credential;

        public _requestHandler(NetworkCredential credential = null) : base()
        {
            _credential = credential;
        }

        public override bool GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
        {
            if (isProxy == true)
            {
                if (_credential == null)
                    throw new NullReferenceException("credential is null");

                callback.Continue(_credential.UserName, _credential.Password);
                return true;
            }

            return false;
        }
    }
}

使用:

        var p = new WebProxy("Scheme://Host:Port", true, new[] { "" }, new NetworkCredential("login", "pass"));
        var p1 = new WebProxy("Scheme://Host:Port", true, new[] { "" }, new NetworkCredential("login", "pass"));
        var p2 = new WebProxy("Scheme://Host:Port", true, new[] { "" }, new NetworkCredential("login", "pass"));

        wb1 = ChromeTest.Create(p1, b => b.Load("http://speed-tester.info/check_ip.php"));
        groupBox1.Controls.Add(wb1);
        wb1.Dock = DockStyle.Fill;

        wb2 = ChromeTest.Create(p2, b => b.Load("http://speed-tester.info/check_ip.php"));
        groupBox2.Controls.Add(wb2);
        wb2.Dock = DockStyle.Fill;

        wb3 = ChromeTest.Create(p, b => b.Load("http://speed-tester.info/check_ip.php"));
        groupBox3.Controls.Add(wb3);
        wb3.Dock = DockStyle.Fill;

答案 3 :(得分:1)

如果您要使用动态代理解析器(proxy hanlder),它允许您对不同的主机使用不同的代理-您应该:

1)准备javascript

var proxy1Str = "PROXY 1.2.3.4:5678";
var proxy2Str = "PROXY 2.3.4.5:6789";

var ProxyPacScript = 
    $"var proxy1 = \"{(proxy1Str.IsNullOrEmpty() ? "DIRECT" : proxy1Str)}\";" +
    $"var proxy2 = \"{(proxy2Str.IsNullOrEmpty() ? "DIRECT" : proxy2Str)}\";" +

    @"function FindProxyForURL(url, host) {
        if (shExpMatch(host, ""*example.com"")) {
            return proxy1;
        }
        return proxy2;
    }";

var bytes = Encoding.UTF8.GetBytes(ProxyPacScript);
var base64 = Convert.ToBase64String(bytes);

2)正确设置

var v = new Dictionary<string, object>();
v["mode"] = "pac_script";
v["pac_url"] = "data:application/x-ns-proxy-autoconfig;base64," + base64;

3)按照接受的答案https://stackoverflow.com/a/36106994/9252162呼叫SetPreference

结果,所有对* example.com的请求将流经proxy1,所有其他请求将流经proxy2。

为此,我花了一整天的时间,但在消息来源(https://cs.chromium.org/)的帮助下,我找到了解决方案。希望对别人有帮助。

主要问题:

1)在新版本(我记得是72或74)中,无法使用“ file:// ...”作为pac_url。

2)我们在cef中无法使用https://developer.chrome.com/extensions/proxy。或者我找不到如何做的方法。

p.s。如何使用其他类型的代理(https,袜子)-https://chromium.googlesource.com/chromium/src/+/master/net/docs/proxy.md#evaluating-proxy-lists-proxy-fallback