Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
# CEFSharp WPF開發(fā)桌面程序?qū)崿F(xiàn)“同一網(wǎng)站多開”
孔乙己顯出極高興的樣子,將兩個(gè)指頭的長指甲敲著柜臺(tái),點(diǎn)頭說:“對呀,對呀!CEFSharp,你用過么?訪問同一網(wǎng)址實(shí)現(xiàn)多開怎么實(shí)現(xiàn)?比如我有3個(gè)淘寶店,我想同時(shí)登錄維護(hù),就像傳說中的指紋瀏覽器那樣實(shí)現(xiàn)cookie和session隔離?”
大家好,我是44歲的大齡程序員碼農(nóng)阿峰。好久沒有開發(fā)過桌面軟件了,記得還是在2018年開發(fā)過winform,這次用wpf實(shí)現(xiàn)了CEFSharp訪問同一網(wǎng)址實(shí)現(xiàn)多開。官方的示例是訪問不同的網(wǎng)站可以互不干擾。其實(shí)搜索引擎剛開始就幫我搜到了解決辦法,不過是我當(dāng)時(shí)沒有意識(shí)到那些文字對我有幫助。幾番趟坑,才得以解決。
1)關(guān)鍵實(shí)現(xiàn)
直接上代碼:
/// <summary>
/// 初始化瀏覽器集合
/// </summary>
public void InitDictionary()
{
foreach (ChatUser user in LocalAccount)
{
if (!Dict.ContainsKey(user.id))
{
#region 初始化ChromiumWebBrowser
string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Cache\\Cache_" + user.id.ToString());
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
var setting = new RequestContextSettings()
{
CachePath = path,
PersistSessionCookies = true,
PersistUserPreferences = true
};
var context = new RequestContext(setting);
var cookieManager = context.GetCookieManager(null);
//這樣設(shè)置的cookie不是全局的,只有當(dāng)前browser才能訪問
cookieManager.SetCookie("dxl.cn", new Cookie
{
Name = $"cookie{user.nickname}",
Value = $"cookievalue{user.nickname}",
Path = path
});
ChromiumWebBrowser chromeBrowser = new ChromiumWebBrowser()
{
Address = config.AppSettings.Settings["ChatUrl"].Value,
RequestContext = context,
MenuHandler = new NullMenuHandler(),
LifeSpanHandler = new LifeSpanHandler(),
Visibility = Visibility.Hidden
};
chromeBrowser.JavascriptObjectRepository.Settings.LegacyBindingEnabled = true;
chromeBrowser.JavascriptObjectRepository.Register("bound", obj, false);
#endregion
obj.WebBrowserCallback += Obj_WebBrowserCallback;
user.msgNum = null;
chromeBrowser.LoadUrl(config.AppSettings.Settings["ChatUrl"].Value.Replace("login", "sso") + $"?token={user.token}");
Dict.Add(user.id, chromeBrowser);
mainWindow.MainGrid.Children.Add(chromeBrowser);
}
}
AccountCountText = $"{LocalAccount.Count}/{config.AppSettings.Settings["MaxAccountCount"].Value}";
if (AccountPlusVisibility != Visibility.Visible)
{
AccountPlusVisibility = Visibility.Hidden;
}
}
這是ViewModel的代碼,下面是頁面的
<Border Grid.Row="1" BorderBrush="Transparent" Background="#f0f0f0" BorderThickness="0" >
<Grid x:Name="MainGrid"/>
</Border>
public void ChangeBrowser(object xaml_obj)
{
var array = xaml_obj as object[];
if (array != null && array.Length == 2)
{
Grid mainGrid = array[0] as Grid;
ChatUser user = array[1] as ChatUser;
if (user != null)
{
CurrentBrowser = Dict[user.id];
foreach (var chromeBrowser in mainGrid.Children)
{
if (chromeBrowser == CurrentBrowser)
{
((ChromiumWebBrowser)chromeBrowser).Visibility = Visibility.Visible;
}
else
{
((ChromiumWebBrowser)chromeBrowser).Visibility = Visibility.Hidden;
}
}
}
}
}
以上是按點(diǎn)擊切換瀏覽器的代碼。
/// <summary>
/// Cef 參數(shù)
/// </summary>
/// <returns></returns>
public static CefSettings GetCefSettings()
{
var settings = new CefSettings
{
Locale = "zh-CN",
AcceptLanguageList = "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
RemoteDebuggingPort = 8088,
LogSeverity = LogSeverity.Disable,
PersistSessionCookies = true,//Persistent Cookies會(huì)被保存在一個(gè)瀏覽器的一個(gè)子文件夾中
UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36",
IgnoreCertificateErrors = true,
MultiThreadedMessageLoop = true,//讓瀏覽器的消息循環(huán)在一個(gè)單獨(dú)的線程中執(zhí)行,建議設(shè)置成true,具體含義看看瀏覽器消息處理。
WindowlessRenderingEnabled = true,//如果不開啟好多用那種JSUI的控件的網(wǎng)站 都有問題
CachePath = AppDomain.CurrentDomain.BaseDirectory + "/Cache",//緩存目錄
};
settings.CefCommandLineArgs.Add("disable-application-cache", "1");//不要緩存
settings.CefCommandLineArgs.Add("disable-gpu", "1");//去掉gpu,否則chrome顯示有問題
settings.CefCommandLineArgs.Add("enable-media-stream", "1"); //Enable WebRTC
settings.CefCommandLineArgs.Add("proxy-auto-detect", "0");
settings.CefCommandLineArgs.Add("no-proxy-server", "1");
settings.CefCommandLineArgs.Add("allow-running-insecure-content", "1");
//settings.CefCommandLineArgs.Add("ppapi-flash-version", "34.0.0.118"); //設(shè)置flash插件版本
//string flashFilePath = Application.StartupPath + @"\Plugins\pepflashplayer.dll";
//settings.CefCommandLineArgs.Add("ppapi-flash-path", flashFilePath);
//settings.CefCommandLineArgs.Add("enable-system-flash", "1");
settings.CefCommandLineArgs.Add("enable-npapi", "1");
settings.CefCommandLineArgs.Add("ppapi-out-of-process", "1");
settings.CefCommandLineArgs.Add("plugin-policy", "allow");
return settings;
}
以上是主程序進(jìn)程啟動(dòng)時(shí)的初始化代碼。
WPF是數(shù)據(jù)驅(qū)動(dòng)這真是比較香,做出來的程序?qū)Ω逥PI設(shè)備支持也好,可惜就是最后打包出來300多M老板接受不了,一番優(yōu)化最后實(shí)現(xiàn)100M以下,奈何一搞C++的后生動(dòng)作比我快,程序打包變態(tài)的小,程序性能貌似也比我的強(qiáng)。所以悲劇了,我最終二選一被PK下來,我的程序最終也是沒有被使用。把關(guān)鍵代碼分享出來,希望可以幫到有需求的人。
var settings = new CefSettings();
settings.CefCommandLineArgs.Add("disable-extensions", "1");
settings.CefCommandLineArgs.Add("disable-plugins", "1");
settings.CefCommandLineArgs.Add("disable-session-storage", "1");
settings.CefCommandLineArgs.Add("disable-web-security", "1");
settings.CefCommandLineArgs.Add("disable-pdf-extension", "1");
settings.CefCommandLineArgs.Add("disable-pdf-viewer", "1");
settings.CefCommandLineArgs.Add("disable-javascript", "1");
settings.CefCommandLineArgs.Add("disable-local-storage", "1");
settings.CefCommandLineArgs.Add("disable-webgl", "1");
settings.CefCommandLineArgs.Add("disable-geolocation", "1");
settings.CefCommandLineArgs.Add("disable-default-apps", "1");
settings.CefCommandLineArgs.Add("disable-remote-fonts", "1");
settings.CefCommandLineArgs.Add("disable-remote-images", "1");
settings.CefCommandLineArgs.Add("disable-remote-scripts", "1");
settings.CefCommandLineArgs.Add("disable-remote-video", "1");
settings.CefCommandLineArgs.Add("disable-remote-webaudio", "1");
var browser = new ChromiumWebBrowser("https://www.example.com", settings);
AI說的辦法我沒有試過,大家說它說得對嗎?
實(shí)驗(yàn)例子,用WPF演示,為什么是WPF,因?yàn)椴幌胗肳INFROM。
本說明示例只做理論描述,開發(fā)操作的基本操作,本文不做敘述,請自行通過其它途徑學(xué)習(xí)。
大致情況如下:
1:創(chuàng)建好WPF項(xiàng)目后,首先在項(xiàng)目中添加包“CefSharp.WPF”,如果你習(xí)慣用WINFROM開發(fā)桌面程序,請使用包:“CefSharp.WINFROM”。WPF和WINFROM選型建議:如果你的項(xiàng)目,對程序外觀有所追求,建議用WPF開發(fā),如果項(xiàng)目對外觀追求不高,那么winfrom開發(fā)速度確實(shí)更快。
2:使用cefsharp加載網(wǎng)頁界面,需要添加引用,引用代碼:
xmlns:cefSharp="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
3:“ChromiumWebBrowser”控件的address屬性中放置您需要加載的網(wǎng)頁地址,此示例只是做簡單的效果演示,故此處只用到前端代碼即可。如果您項(xiàng)目需要對網(wǎng)頁做大量的個(gè)性化處理,則可以用C#后端代碼實(shí)現(xiàn)。
前端代碼如下:
備注:CefSharp是一套基于Google瀏覽器引擎的開源框架。如果你對其有更多的想法, 請移步以下地址,了解更多用途用法。
github開源地址:https://github.com/cefsharp/CefSharp
本91
直接上代碼:
替換下這個(gè)工具類即可。
不明白的進(jìn)群加好友咨詢。
*請認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。