C# CEF3在运行时设置代理 下载了CEF(CurrMuxEngultFramework)二进制分发(CeFclipse和CEFSIGLE)C++实例,实现了CEFCube在运行时可以更改代理设置。

C# CEF3在运行时设置代理 下载了CEF(CurrMuxEngultFramework)二进制分发(CeFclipse和CEFSIGLE)C++实例,实现了CEFCube在运行时可以更改代理设置。,c#,c++,proxy,chromium-embedded,cefsharp,C#,C++,Proxy,Chromium Embedded,Cefsharp,实现这一点的关键是获取RequestContext并调用函数SetPreference 在客户端上,一切都很好 但是在CefSharp上,调用SetPreference总是返回false,并且对于首选项名称“proxy”,HasPreference也会返回false。多亏了主动增强更改请求上下文优先级的正确方法,在CEF UIThread上运行代码,如下所示: Cef.UIThreadTaskFactory.StartNew(delegate { var rc = thi

实现这一点的关键是获取RequestContext并调用函数SetPreference

在客户端上,一切都很好

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

多亏了主动增强更改请求上下文优先级的正确方法,在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=""
    });
Cef.UIThreadTaskFactory.StartNew(委托{
var rc=this.browser.GetBrowser().GetHost().RequestContext;
var v=新字典();
v[“模式”]=“固定服务器”;
v[“服务器”]=“scheme://host:port";
字符串错误;
bool success=rc.SetPreference(“proxy”,v,out error);
//success=true,error=“”
});

如果有人需要其他解决方案,我找到了这个解决方案

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);

        });
Cef.UIThreadTaskFactory.StartNew(委托
{
字符串ip=“ip或地址”;
字符串port=“port”;
var rc=this.browser.GetBrowser().GetHost().RequestContext;
var dict=新字典();
添加(“模式”、“固定服务器”);
dict.Add(“服务器”,“ip+”:“+端口+”);
字符串错误;
bool success=rc.SetPreference(“代理”,dict,out错误);
});

我下载了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;
        }
    }
}

如果您需要动态代理解析程序(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;
var v=newdictionary();
v[“模式”]=“pac_脚本”;
v[“pac_url”]=“数据:应用程序/x-ns-proxy-autoconfig;base64,”+base64;
3) 呼叫SetPreference,如已接受的应答中所示

因此,对*example.com的所有请求都将通过proxy1,其他所有请求将通过proxy2

为此,我花了一整天的时间,但在source()的帮助下,我找到了解决方案。希望它能帮助别人

主要问题:

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

2) 我们不能在cef中使用。。或者我找不到怎么做


p、 如何使用另一种类型的代理(https、socks)

跳转到
Gitter
,阅读昨天的对话,了解所有需要的详细信息。可能您调用的线程不正确,只有一个线程可以工作。非常感谢,A想知道如何在正确的线程上运行代码,但是我被C++和C包装之间的代码差异分散了注意力。我正在尝试“修改一个不是用户可修改的引用”@ AAMITLAN,请您描述一下上面的位置和方式。我想在Cef.Initialized之后在运行时更改代理,请告诉我。谢谢,我尝试了上面的方法,但是没有任何效果。它仍然使用我的默认ip,有什么建议吗?锁定的目的是什么?您正在执行的任何操作都不需要锁定。这根绳子是干什么用的?应已在cef ui线程上调用IsBrowserInitializedChanged,无需创建任务。保留对您创建的RequestContext的引用,并简化您的代码。您还应包括您正在使用的CefSharp版本。请改进对源代码的描述。否则,这篇文章似乎并没有为这个问题提供答案。请编辑您的答案,或者将其作为问题的注释发布。谢谢@amaitland,很抱歉,我没有完全清理工作解决方案中的代码,并留下了一些片段。我已经根据您的注释编辑了代码。@amaitland,现在表达式rc.SetPreference(“proxy”,v,out string error)抛出System.NullReferenceException,我检查了rc.Equals(br.GetBrowser().GetHost().RequestContext),结果为false。我希望rc只是对当前RequestContext的引用。这是正常的行为吗?如果没有stacktrace,我真的不能说。示例看起来不完整,您构建的包url,实际上没有调用SetPreference,最好显示一个完整的示例。忘记它。谢谢添加步骤#3。
var v = new Dictionary<string, object>();
v["mode"] = "pac_script";
v["pac_url"] = "data:application/x-ns-proxy-autoconfig;base64," + base64;