CEFSharp 应用程序显示空白屏幕,然后在一分钟后自行响应
CEFSharp app displays blank screen and then responds on it's own after a minute
我一直在开发一个应用程序,它使用 CEFSharp(版本 83.4.20)加载我公司的 VOIP 平台(engage.ringcentral.com)。来源在 Github https://github.com/dylanlangston/EngageRC
该应用程序已经运行了大约一个月,在将其投入生产后,我收到了一个奇怪问题的报告。人们看到的是空白屏幕,无法与网页交互(
Example of issue)。几分钟后,问题似乎自行解决,并且他们能够再次与网页进行交互。我自己无法重现该问题。
我认为这可能是渲染问题。到目前为止,我已经尝试在我的应用程序中调整以下内容:
删除下面的行。
settings.CefCommandLineArgs.Add("disable-gpu");
settings.CefCommandLineArgs.Add("disable-gpu-shader-disk-cache", "1");
将它们替换为。
settings.CefCommandLineArgs.Add("disable-gpu-compositing");
不幸的是,这并没有解决问题,我不确定我遗漏了什么。
CEF Initialization的相关代码位于InitializeChromium方法下的https://github.com/dylanlangston/EngageRC/blob/master/Windows/MainWindow.Designer.cs。见下文
//
// Chrome
//
private CefSharp.WinForms.ChromiumWebBrowser chromeBrowser;
public ChromiumWebBrowser InitializeChromium(string URL, string Name)
{
// Check if already Initialized
if (Cef.IsInitialized == false)
{
CefSettings settings = new CefSettings();
// Enable Logging if debugging or console window
if (!this.debug || !this.console)
{
settings.LogSeverity = LogSeverity.Disable;
}
else
{
settings.LogSeverity = LogSeverity.Verbose;
}
// Enable Microphone settings
settings.CefCommandLineArgs.Add("enable-media-stream", "1");
// Set Custom Browser Paths
settings.CefCommandLineArgs.Add("disable-gpu-shader-disk-cache", "1");
// Disable GPU to fix rendering issues on some machines.
settings.CefCommandLineArgs.Add("disable-gpu");
// Disable CORS protection (cross site scripting) which the engage.ringcentral.com site doesn't seem to like/respect, disabled as the website doesn't seem to improve with this turned on.
//settings.CefCommandLineArgs.Add("disable-web-security");
// Enable session Cookie persistence, disabled as it's unneeded.
//settings.PersistSessionCookies = true;
// Custom Browser paths
settings.BrowserSubprocessPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\CEFSharp\CefSharp.BrowserSubprocess.exe");
settings.LocalesDirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\CEFSharp\locales\");
settings.ResourcesDirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\CEFSharp\");
// Check if Resources folder is writable. If it isn't then write to application data.
DirectoryInfo di = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\CEFSharp\"));
if ((di.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
{
settings.RootCachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"EngageRC\CEFSharp\cache");
settings.CachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"EngageRC\CEFSharp\cache");
settings.LogFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"EngageRC\CEFSharp\debug.log");
}
else
{
settings.RootCachePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\CEFSharp\cache");
settings.CachePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\CEFSharp\cache");
settings.LogFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\CEFSharp\debug.log");
}
// Initialize cef with the provided settings or add new tab
Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);
}
// Create a browser component
chromeBrowser = new ChromiumWebBrowser(URL);
// Set Name
chromeBrowser.Name = Name;
// Adjust size and scaling
this.chromeBrowser.Dock = DockStyle.Fill;
this.chromeBrowser.Width = this.Width;
this.chromeBrowser.Height = this.Height;
// Add control
this.Controls.Add(chromeBrowser);
// Bring to front
this.chromeBrowser.BringToFront();
// Set label to Goodbye.
this.label1.Text = "Goodbye";
// Return control
return chromeBrowser;
}
我无法找到我的 Google foo 之前的任何问题,所以这似乎不是其他人看到的他们的应用程序。关于 C#,我仍在学习中,所以这 100% 可能是我自己的错,我做错了什么。
我能够从遇到问题的机器上获得详细的日志记录。我主要看到以下错误。 https://gist.github.com/dylanlangston/194e389ead437e6c6fe08b2d4746bf43
处的完整日志
[0729/083616.491:ERROR:paint_controller.cc(646)] PaintController::FinishCycle() completed
感谢任何有助于解决此问题的想法或建议!
更新: 根据@amaitland 的有用评论,似乎这种行为可能是由于在我不应该的线程上使用 Thread.Sleep 引起的。
查看我的代码后,我发现我在两个位置都有这个。
首先,我调用 thread.sleep 等待浏览器缩放级别与我保存到 windows 独立存储的值相匹配。这不应该 运行ning 除非应用程序首次启动。我不认为这是问题所在,但为了安全起见,我还是将其发布在这里。 (https://github.com/dylanlangston/EngageRC/blob/master/CEFSharpHandlers.cs)
public void OnLoadingStateChanged(object sender, LoadingStateChangedEventArgs args)
{
ChromiumWebBrowser chrome = (ChromiumWebBrowser)sender;
if (!args.IsLoading) // Loading finished.
{
// If first load set zoom level to previous level
if (firstLoad < 3)
{
try
{
double zoom = double.Parse(ConfigReader.ReadIsolatedStorage("z"), System.Globalization.CultureInfo.InvariantCulture);
while (args.Browser.GetZoomLevelAsync().Result != zoom) { chrome.SetZoomLevel(zoom); Thread.Sleep(50); }
}
catch { }
firstLoad++;
}
// These JS and CSS modifications built into EngageRC
string hotfixJS = "";
string hotfixCSS = "/* Fix for dropdowns */ ul.dropdown-menu[style=\\"opacity: 1;\\"] {display: block !important; } /* End fix for dropdowns */";
// Inject custom javascript and css code on page load
chrome.ExecuteScriptAsync(hotfixJS);
chrome.ExecuteScriptAsync("var engageRCSS = document.getElementById('EngageRCSS'); if (!engageRCSS) { var node = document.createElement('style'); node.setAttribute('id', 'EngageRCSS'); node.innerHTML = \"" + hotfixCSS +"\"; document.body.appendChild(node); }");
if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\Custom.js"))) { chrome.ExecuteScriptAsync(System.IO.File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\Custom.js"))); }
if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\Custom.css"))) { chrome.ExecuteScriptAsync("var customCSS = document.getElementById('customcss'); if (!customCSS) { var node = document.createElement('style'); node.setAttribute('id', 'customcss'); node.innerHTML = \"" + System.IO.File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\Custom.css")).Replace("\n", String.Empty).Replace("\r", String.Empty).Replace("\t", String.Empty).Replace("\"", "\\"") + "\"; document.body.appendChild(node); }"); }
}
}
我在显示通知的时候也有。这很可能是我的问题,因为这是主应用程序线程中的 运行ning... (https://github.com/dylanlangston/EngageRC/blob/master/NotificationSupport.cs)
public void displayNotification(string Title = "EngageRC", string Message = "")
{
// Display notification for 5 seconds
Notify notification = MainWindow.notification;
try
{
if (!IsActive(hWnd)) // Check if application is already active.
{
string config = ConfigReader.GetConfigValue("NotificationsDisabled").ToLower();
if (!(config == "true" || config == "1"))
{
notification.NewNotification(Title, Message, 5000);
}
config = ConfigReader.GetConfigValue("GetFocusOnCallDisabled").ToLower();
if (!(config == "true" || config == "1") && (Message == "You have incoming call"))
{
// Minimize window
ShowWindow(hWnd, 0x02);
// Restore window to previous state.
ShowWindow(hWnd, 0x09);
}
config = ConfigReader.GetConfigValue("GetFocusOnPendingDispositionDisabled").ToLower();
if (!(config == "true" || config == "1") && (Message == "You have a disposition pending"))
{
// Minimize window
ShowWindow(hWnd, 0x02);
// Restore window to previous state.
ShowWindow(hWnd, 0x09);
}
}
}
catch { notification.SetIconVisible(false); }
finally
{
Thread.Sleep(4999);
notification.SetIconVisible(false);
}
}
根据我所听到的,我应该在与主应用程序不同的线程上制作通知表单 运行 吗?还是我跑题了?
更新:
我能够将通知移到它自己的线程中。我正在关闭这个问题,并将让用户测试黑屏是否仍然存在。
再次感谢您的帮助!!
@amaitland 的评论有助于缩小此问题的范围。
我一直在开发一个应用程序,它使用 CEFSharp(版本 83.4.20)加载我公司的 VOIP 平台(engage.ringcentral.com)。来源在 Github https://github.com/dylanlangston/EngageRC
该应用程序已经运行了大约一个月,在将其投入生产后,我收到了一个奇怪问题的报告。人们看到的是空白屏幕,无法与网页交互( Example of issue)。几分钟后,问题似乎自行解决,并且他们能够再次与网页进行交互。我自己无法重现该问题。
我认为这可能是渲染问题。到目前为止,我已经尝试在我的应用程序中调整以下内容:
删除下面的行。
settings.CefCommandLineArgs.Add("disable-gpu");
settings.CefCommandLineArgs.Add("disable-gpu-shader-disk-cache", "1");
将它们替换为。
settings.CefCommandLineArgs.Add("disable-gpu-compositing");
不幸的是,这并没有解决问题,我不确定我遗漏了什么。
CEF Initialization的相关代码位于InitializeChromium方法下的https://github.com/dylanlangston/EngageRC/blob/master/Windows/MainWindow.Designer.cs。见下文
//
// Chrome
//
private CefSharp.WinForms.ChromiumWebBrowser chromeBrowser;
public ChromiumWebBrowser InitializeChromium(string URL, string Name)
{
// Check if already Initialized
if (Cef.IsInitialized == false)
{
CefSettings settings = new CefSettings();
// Enable Logging if debugging or console window
if (!this.debug || !this.console)
{
settings.LogSeverity = LogSeverity.Disable;
}
else
{
settings.LogSeverity = LogSeverity.Verbose;
}
// Enable Microphone settings
settings.CefCommandLineArgs.Add("enable-media-stream", "1");
// Set Custom Browser Paths
settings.CefCommandLineArgs.Add("disable-gpu-shader-disk-cache", "1");
// Disable GPU to fix rendering issues on some machines.
settings.CefCommandLineArgs.Add("disable-gpu");
// Disable CORS protection (cross site scripting) which the engage.ringcentral.com site doesn't seem to like/respect, disabled as the website doesn't seem to improve with this turned on.
//settings.CefCommandLineArgs.Add("disable-web-security");
// Enable session Cookie persistence, disabled as it's unneeded.
//settings.PersistSessionCookies = true;
// Custom Browser paths
settings.BrowserSubprocessPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\CEFSharp\CefSharp.BrowserSubprocess.exe");
settings.LocalesDirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\CEFSharp\locales\");
settings.ResourcesDirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\CEFSharp\");
// Check if Resources folder is writable. If it isn't then write to application data.
DirectoryInfo di = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\CEFSharp\"));
if ((di.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
{
settings.RootCachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"EngageRC\CEFSharp\cache");
settings.CachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"EngageRC\CEFSharp\cache");
settings.LogFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"EngageRC\CEFSharp\debug.log");
}
else
{
settings.RootCachePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\CEFSharp\cache");
settings.CachePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\CEFSharp\cache");
settings.LogFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\CEFSharp\debug.log");
}
// Initialize cef with the provided settings or add new tab
Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);
}
// Create a browser component
chromeBrowser = new ChromiumWebBrowser(URL);
// Set Name
chromeBrowser.Name = Name;
// Adjust size and scaling
this.chromeBrowser.Dock = DockStyle.Fill;
this.chromeBrowser.Width = this.Width;
this.chromeBrowser.Height = this.Height;
// Add control
this.Controls.Add(chromeBrowser);
// Bring to front
this.chromeBrowser.BringToFront();
// Set label to Goodbye.
this.label1.Text = "Goodbye";
// Return control
return chromeBrowser;
}
我无法找到我的 Google foo 之前的任何问题,所以这似乎不是其他人看到的他们的应用程序。关于 C#,我仍在学习中,所以这 100% 可能是我自己的错,我做错了什么。
我能够从遇到问题的机器上获得详细的日志记录。我主要看到以下错误。 https://gist.github.com/dylanlangston/194e389ead437e6c6fe08b2d4746bf43
处的完整日志[0729/083616.491:ERROR:paint_controller.cc(646)] PaintController::FinishCycle() completed
感谢任何有助于解决此问题的想法或建议!
更新: 根据@amaitland 的有用评论,似乎这种行为可能是由于在我不应该的线程上使用 Thread.Sleep 引起的。
查看我的代码后,我发现我在两个位置都有这个。
首先,我调用 thread.sleep 等待浏览器缩放级别与我保存到 windows 独立存储的值相匹配。这不应该 运行ning 除非应用程序首次启动。我不认为这是问题所在,但为了安全起见,我还是将其发布在这里。 (https://github.com/dylanlangston/EngageRC/blob/master/CEFSharpHandlers.cs)
public void OnLoadingStateChanged(object sender, LoadingStateChangedEventArgs args)
{
ChromiumWebBrowser chrome = (ChromiumWebBrowser)sender;
if (!args.IsLoading) // Loading finished.
{
// If first load set zoom level to previous level
if (firstLoad < 3)
{
try
{
double zoom = double.Parse(ConfigReader.ReadIsolatedStorage("z"), System.Globalization.CultureInfo.InvariantCulture);
while (args.Browser.GetZoomLevelAsync().Result != zoom) { chrome.SetZoomLevel(zoom); Thread.Sleep(50); }
}
catch { }
firstLoad++;
}
// These JS and CSS modifications built into EngageRC
string hotfixJS = "";
string hotfixCSS = "/* Fix for dropdowns */ ul.dropdown-menu[style=\\"opacity: 1;\\"] {display: block !important; } /* End fix for dropdowns */";
// Inject custom javascript and css code on page load
chrome.ExecuteScriptAsync(hotfixJS);
chrome.ExecuteScriptAsync("var engageRCSS = document.getElementById('EngageRCSS'); if (!engageRCSS) { var node = document.createElement('style'); node.setAttribute('id', 'EngageRCSS'); node.innerHTML = \"" + hotfixCSS +"\"; document.body.appendChild(node); }");
if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\Custom.js"))) { chrome.ExecuteScriptAsync(System.IO.File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\Custom.js"))); }
if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\Custom.css"))) { chrome.ExecuteScriptAsync("var customCSS = document.getElementById('customcss'); if (!customCSS) { var node = document.createElement('style'); node.setAttribute('id', 'customcss'); node.innerHTML = \"" + System.IO.File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\Custom.css")).Replace("\n", String.Empty).Replace("\r", String.Empty).Replace("\t", String.Empty).Replace("\"", "\\"") + "\"; document.body.appendChild(node); }"); }
}
}
我在显示通知的时候也有。这很可能是我的问题,因为这是主应用程序线程中的 运行ning... (https://github.com/dylanlangston/EngageRC/blob/master/NotificationSupport.cs)
public void displayNotification(string Title = "EngageRC", string Message = "")
{
// Display notification for 5 seconds
Notify notification = MainWindow.notification;
try
{
if (!IsActive(hWnd)) // Check if application is already active.
{
string config = ConfigReader.GetConfigValue("NotificationsDisabled").ToLower();
if (!(config == "true" || config == "1"))
{
notification.NewNotification(Title, Message, 5000);
}
config = ConfigReader.GetConfigValue("GetFocusOnCallDisabled").ToLower();
if (!(config == "true" || config == "1") && (Message == "You have incoming call"))
{
// Minimize window
ShowWindow(hWnd, 0x02);
// Restore window to previous state.
ShowWindow(hWnd, 0x09);
}
config = ConfigReader.GetConfigValue("GetFocusOnPendingDispositionDisabled").ToLower();
if (!(config == "true" || config == "1") && (Message == "You have a disposition pending"))
{
// Minimize window
ShowWindow(hWnd, 0x02);
// Restore window to previous state.
ShowWindow(hWnd, 0x09);
}
}
}
catch { notification.SetIconVisible(false); }
finally
{
Thread.Sleep(4999);
notification.SetIconVisible(false);
}
}
根据我所听到的,我应该在与主应用程序不同的线程上制作通知表单 运行 吗?还是我跑题了?
更新: 我能够将通知移到它自己的线程中。我正在关闭这个问题,并将让用户测试黑屏是否仍然存在。
再次感谢您的帮助!!
@amaitland 的评论有助于缩小此问题的范围。