how to get favicon of visited site
This isn't an issue related to CefSharp. If you want to learn how to get a favicon from a website, you can search Google for a way, but here's the easiest (taken from this StackOverflow question):
string url = ""; // Replace with your URL
using (WebClient client = new WebClient())
client.DownloadFile(string.Format("http://getfavicon.appspot.com/{0}", url), "icon.ico");
The site's favicon would then be in a file called "icon.ico," or whatever you decide to rename it.
Good point, @csdevrich. Of course we could add hooks for this in CefSharp also. @asarchit65 - is that what you're after? Please explain your use case more carefully. Closing for now.
For anyone looking at this in the future, the method should be updated to this:
string url = ""; // Replace with your URL
using (WebClient client = new WebClient())
client.DownloadFile(string.Format("http://www.google.com/s2/favicons?domain={0}", url), "icon.ico");
Complete class implementing IDisplayHandler to only get the favicon.ico from website root and binding to a WPF Window's icon. For people's reference should they come across this issue in the future.
Might not be the best piece of code... enthusiast coder here.
```C#
class DisplayHandler : IDisplayHandler, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private object _favIcon;
/// <summary>
/// For binding to System.Windows.Window.Icon.
/// </summary>
public object FavIcon {
get { return _favIcon; }
set { _favIcon = value; OnPropertyChanged("FavIcon"); }
}
private BitmapDecoder _decoder;
private BitmapDecoder Decoder {
get => _decoder;
set {
if (_decoder != null) _decoder.DownloadCompleted -= decoderDownloadCompleted;
_decoder = value;
if (_decoder != null) _decoder.DownloadCompleted += decoderDownloadCompleted;
}
}
private void decoderDownloadCompleted(object sender, EventArgs e)
{
FavIcon = Decoder.Frames.OrderBy(f => f.Width).FirstOrDefault();
Decoder = null;
}
protected void OnPropertyChanged(string propertyName)
{
if (!Application.Current.Dispatcher.CheckAccess())
Application.Current.Dispatcher.Invoke(() => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)));
else PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public void OnAddressChanged(IWebBrowser chromiumWebBrowser, AddressChangedEventArgs addressChangedArgs)
{
}
public bool OnAutoResize(IWebBrowser chromiumWebBrowser, IBrowser browser, CefSharp.Structs.Size newSize)
{
return false;
}
public bool OnConsoleMessage(IWebBrowser chromiumWebBrowser, ConsoleMessageEventArgs consoleMessageArgs)
{
return false;
}
public void OnFaviconUrlChange(IWebBrowser chromiumWebBrowser, IBrowser browser, IList<string> urls)
{
var baseUrl = new Uri(browser.MainFrame.Url).GetLeftPart(UriPartial.Authority);
Application.Current.Dispatcher.Invoke(() =>
{
Decoder = BitmapDecoder.Create(new Uri(baseUrl + "/favicon.ico"), BitmapCreateOptions.None, BitmapCacheOption.OnDemand);
});
}
public void OnFullscreenModeChange(IWebBrowser chromiumWebBrowser, IBrowser browser, bool fullscreen)
{
}
public void OnLoadingProgressChange(IWebBrowser chromiumWebBrowser, IBrowser browser, double progress)
{
}
public void OnStatusMessage(IWebBrowser chromiumWebBrowser, StatusMessageEventArgs statusMessageArgs)
{
}
public void OnTitleChanged(IWebBrowser chromiumWebBrowser, TitleChangedEventArgs titleChangedArgs)
{
}
public bool OnTooltipChanged(IWebBrowser chromiumWebBrowser, ref string text)
{
return false;
}
}
And the Window.xaml:
```XAML
<Window ...
Icon="{Binding ElementName=Browser_DisplayHandler, Mode=OneWay, Path=FavIcon, TargetNullValue=browser.ico}">
<wpf:ChromiumWebBrowser>
<wpf:ChromiumWebBrowser.DisplayHandler>
<local:DisplayHandler x:Name="Browser_DisplayHandler"/>
</wpf:ChromiumWebBrowser.DisplayHandler>
</wpf:ChromiumWebBrowser>
</Window>
Most helpful comment
http://cefsharp.github.io/api/63.0.0/html/M_CefSharp_IDisplayHandler_OnFaviconUrlChange.htm