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