Closed ghost closed 9 years ago
As a general rule we'd prefer you to fork MinimalExample
when demonstrating problems like this (https://github.com/cefsharp/CefSharp.MinimalExample) or at a minimum post your cost as a Gist
or similar
. See https://github.com/cefsharp/CefSharp/blob/master/CONTRIBUTING.md#what-should-i-include-when-creating-an-issue
As a general rule it's not great to completely change the UserAgent
, better just to append your own custom tag at the end. Too many websites use UserAgent
detection based on the string.
If you add c#
to your code blocks they actually get highlighted properly (you can see I edited your post).
What does the debug.log
file say? (Just an excerpt if anything stands out is fine, ignore anything about sand boxing)
Sorry about not providing the correct example, I shall certainly do that in the future.
I agree with you on the User Agent, but even one of the standard ones (Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36
) causes it.
Below is the last part of the log. After the first line, I press a button (causing Shutdown to be called) and it freezes there.
[0804/120026:VERBOSE1:resource_loader.cc(778)] ResponseCompleted: http://cdn.livechatinc.com/sounds/message.ogg
[0804/120026:ERROR:audio_low_latency_output_win.cc(181)] Bailing out due to non-perfect timing. Buffer size of 480 is not an even divisor of 1056
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120027:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120056:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120056:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120056:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120056:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120056:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120056:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120056:VERBOSE1:ipc_sync_channel.cc(386)] Canceling pending sends
[0804/120056:VERBOSE1:statistics_recorder.cc(294)] Collections of all histograms
Histogram: GPU.CollectContextGraphicsInfo recorded 1 samples, average = 0.0 (flags = 0x1)
At the end it has some histograms, doesn't seem that relevant to me (I could be wrong!)
You can get console messages as well https://github.com/cefsharp/CefSharp/blob/cefsharp/41/CefSharp/IWebBrowser.cs#L16
Even though your in OffScreen
you can likely still open DevTools
(just remember to close it before disposing of the browser). So you can likely see what's going on under the hood.
Sorry about not providing the correct example, I shall certainly do that in the future.
It's fine, just makes our helping you a lot easier if we can simply download a ready to run example :+1:
Seems related to https://bitbucket.org/chromiumembedded/cef/issues/1115/cefshutdown-crash
Possibly, that references a very old version of CEF
.
Can you test again with master
? It's a newer version of CEF
again, plus a major rewrite (some of the methods have changed, so it won't just be a copy and paste job exactly, shouldn't be too much effort though).
Sure! master
's NuGet still picks up CEF 3.2272.32 though. I can build it against a higher version by manually downloading latest CEF :)
NuGet still picks up CEF 3.2272.32 though
Reference? It should be pointing to 3.2357.1274
https://github.com/cefsharp/CefSharp/blob/master/build.ps1#L10
Does your WebRequest
finish before you attempt to Shutdown
? Most handlers including OnBeforeResourceLoad
actually execute on a CEF
thread, so it's best not to block them or you'll get issues. Can you spawn your processing off into a Task
?
I tried spawning them in a Task, same thing happened. Even blocked the event thread by Thread.Sleep(1000)
took a while but still exited cleanly. Ill try with master
, seem to have mixed up the versions.
Just did a quick test with a timeout on the WebRequest, so they should all complete. None timed out I think and it stll froze.
Ok, got master
working now, give me a minute while I retry my tests.
Still happens on master
, here's the example again:
// Copyright © 2010-2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Threading.Tasks;
using CefSharp.Example;
using System.Net;
namespace CefSharp.OffScreen.Example
{
public class Program
{
private const string TestUrl = "http://livechatinc.com/";
public static void Main(string[] args)
{
Console.WriteLine("This example application will load {0}, take a screenshot, and save it to your desktop.", TestUrl);
Console.WriteLine("You may see a lot of Chromium debugging output, please wait...");
Console.WriteLine();
// You need to replace this with your own call to Cef.Initialize();
//CefExample.Init();
Cef.Initialize(new CefSettings() { UserAgent = "MyBeautifulUserAgent", LogSeverity = LogSeverity.Disable });
MainAsync("cachePath1", 1.0);
//Demo showing Zoom Level of 3.0
//Using seperate request contexts allows the urls from the same domain to have independent zoom levels
//otherwise they would be the same - default behaviour of Chromium
//MainAsync("cachePath2", 3.0);
// We have to wait for something, otherwise the process will exit too soon.
Console.ReadKey();
// Clean up Chromium objects. You need to call this in your application otherwise
// you will get a crash when closing.
Cef.Shutdown();
}
private static async void MainAsync(string cachePath, double zoomLevel)
{
var browserSettings = new BrowserSettings();
var requestContextSettings = new RequestContextSettings { CachePath = cachePath };
// RequestContext can be shared between browser instances and allows for custom settings
// e.g. CachePath
using(var requestContext = new RequestContext(requestContextSettings))
using (var browser = new ChromiumWebBrowser(TestUrl, browserSettings, requestContext))
{
browser.RequestHandler = new MyBeautifulRequestHandler();
browser.ConsoleMessage += browser_ConsoleMessage;
browser.StatusMessage += browser_StatusMessage;
if (zoomLevel > 1)
{
browser.FrameLoadStart += (s, argsi) =>
{
var b = (ChromiumWebBrowser)s;
if (argsi.IsMainFrame)
{
b.SetZoomLevel(zoomLevel);
}
};
}
await LoadPageAsync(browser);
// Wait for the screenshot to be taken.
await browser.ScreenshotAsync().ContinueWith(DisplayBitmap);
//await LoadPageAsync(browser, "http://github.com");
// Wait for the screenshot to be taken.
//await browser.ScreenshotAsync().ContinueWith(DisplayBitmap);
}
}
static void browser_ConsoleMessage(object sender, ConsoleMessageEventArgs e)
{
Console.WriteLine("============================================================================");
Console.WriteLine("[" + e.Source + "][" + e.Line + "]" + e.Message);
Console.WriteLine("============================================================================");
}
static void browser_StatusMessage(object sender, StatusMessageEventArgs e)
{
Console.WriteLine("============================================================================");
Console.WriteLine(e.Value);
Console.WriteLine("============================================================================");
}
public static Task LoadPageAsync(IWebBrowser browser, string address = null)
{
var tcs = new TaskCompletionSource<bool>();
EventHandler<LoadingStateChangedEventArgs> handler = null;
handler = (sender, args) =>
{
//Wait for while page to finish loading not just the first frame
if (!args.IsLoading)
{
browser.LoadingStateChanged -= handler;
tcs.TrySetResult(true);
}
};
browser.LoadingStateChanged += handler;
if (!string.IsNullOrEmpty(address))
{
browser.Load(address);
}
return tcs.Task;
}
private static void DisplayBitmap(Task<Bitmap> task)
{
// Make a file to save it to (e.g. C:\Users\jan\Desktop\CefSharp screenshot.png)
var screenshotPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "CefSharp screenshot" + DateTime.Now.Ticks + ".png");
Console.WriteLine();
Console.WriteLine("Screenshot ready. Saving to {0}", screenshotPath);
var bitmap = task.Result;
// Save the Bitmap to the path.
// The image type is auto-detected via the ".png" extension.
bitmap.Save(screenshotPath);
// We no longer need the Bitmap.
// Dispose it to avoid keeping the memory alive. Especially important in 32-bit applications.
bitmap.Dispose();
Console.WriteLine("Screenshot saved. Launching your default image viewer...");
// Tell Windows to launch the saved image.
Process.Start(screenshotPath);
Console.WriteLine("Image viewer launched. Press any key to exit.");
}
}
public class MyBeautifulRequestHandler : IRequestHandler
{
public bool OnBeforeBrowse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, bool isRedirect)
{
return false;
}
public bool OnCertificateError(IWebBrowser browserControl, IBrowser browser, CefErrorCode errorCode, string requestUrl, IRequestCallback callback)
{
return true;
}
public void OnPluginCrashed(IWebBrowser browserControl, IBrowser browser, string pluginPath)
{
Console.WriteLine("Not interested in this one");
}
public CefReturnValue OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback)
{
Console.Write(request.Url);
WebRequest webRequest = HttpWebRequest.Create(request.Url);
webRequest.Method = "HEAD";
webRequest.Proxy = null;
webRequest.Timeout = 5000;
try
{
using (WebResponse webResponse = webRequest.GetResponse())
{
if (webResponse.ContentLength != -1)
{
Console.Write(":" + webResponse.ContentLength);
}
}
}
catch (Exception ex)
{
Console.Write(":EX=" + ex.Message);
}
Console.WriteLine(":Done");
callback.Continue(true);
return CefReturnValue.Continue;
}
public bool GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
{
return false;
}
public bool OnBeforePluginLoad(IWebBrowser browserControl, IBrowser browser, string url, string policyUrl, WebPluginInfo info)
{
return false;
}
public void OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status)
{
Console.WriteLine("Render process terminated");
}
public bool OnQuotaRequest(IWebBrowser browserControl, IBrowser browser, string originUrl, long newSize, IRequestCallback callback)
{
callback.Continue(true);
return false;
}
public void OnResourceRedirect(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, ref string newUrl)
{
Console.WriteLine("OnResourceRedirect");
}
public bool OnProtocolExecution(IWebBrowser browserControl, IBrowser browser, string url)
{
return true;
}
public void OnFaviconUrlChange(IWebBrowser browserControl, IBrowser browser, System.Collections.Generic.IList<string> urls)
{
}
}
}
Debug log looks about the same as it did before. Still hangs on GC::WaitForPendingFinalizers()
. After testing this I disabled the logging so I could see potential javascript and status messages (none showed)
For master
at least you shouldn't perform long running tasks in the OnBeforeResourceLoad
method it's self. Try https://gist.github.com/amaitland/7cb77867e45db4aff00b#file-program-cs-L168
That did it for some reason. Already tried that on the older version and for some reason still isn't working there. I'll just switch over to the latest version to remedy the issue :+1:
master
has much better support for async operations. Previously versions hide much of the implementation detail which can cause problems, like this one.
Bear with me here. I've got a very very strange bug and it only happens in the following situation:
OnBeforeResourceLoad
. Not sure what this code needs to do, I've tried many different things but only the code in the example below causes itOnly if all these things are true, it will hang on Cef.Shutdown() on GC::WaitForPendingFinalizers().
The combination of conditions smells like a Javascript bug and livechatinc's Javascript probably chokes on a non-standard user agents. Below I've included the modified Offscreen.Example.