How to allow and manipulate downloads in Cefsharp

By FoxLearn 7/2/2024 8:59:18 AM   37
CefSharp is a .NET library that wraps around the Chromium Embedded Framework, allowing you to embed Chromium-based browsers in .NET applications.

By default, when embedding a Chromium-based browser in WinForms using the CefSharp library, attempting to download a file from a webpage often results in no visible interaction or progress:

  1. Clicking a download button or link on a webpage doesn't trigger any download-related action.
  2. There's no prompt to specify a download location or any indication of a download starting.
  3. The downloaded file doesn't appear to be saved anywhere, and there's no download progress visible.

This behavior occurs because CefSharp does not handle downloads out-of-the-box without additional configuration and implementation. To manipulate downloads in cefsharp, you need to implement a DownloadHandler.

public class CustomDownloadHandler : IDownloadHandler
{
    public event EventHandler<DownloadItem> OnBeforeDownloadFired;
    public event EventHandler<DownloadItem> OnDownloadUpdatedFired;

    public void OnBeforeDownload(IWebBrowser chromiumWebBrowser, IBrowser browser, DownloadItem downloadItem, IBeforeDownloadCallback callback)
    {
        if (downloadItem.IsValid){
            // you can get file information
        }

        OnBeforeDownloadFired?.Invoke(this, downloadItem);

        if (!callback.IsDisposed)
        {
              using (callback)
              {
                    callback.Continue(
                        downloadItem.SuggestedFileName,
                        showDialog: true
                    );
              }
         }
    }

    public void OnDownloadUpdated(IWebBrowser chromiumWebBrowser, IBrowser browser, DownloadItem downloadItem, IDownloadItemCallback callback)
    {
         OnDownloadUpdatedFired?.Invoke(this, downloadItem);

         if (downloadItem.IsValid)
         {
             // Show progress of the download
             if (downloadItem.IsInProgress && (downloadItem.PercentComplete != 0))
             {
                  //"Current Download Speed: {0} bytes ({1}%)", downloadItem.CurrentSpeed, downloadItem.PercentComplete
             }
             if (downloadItem.IsComplete)
             {
                  //The download has been finished
             }
         }
    }
}

Initialize CefSharp Browser with Custom DownloadHandler class.

// Initialize cef with the provided settings
var settings = new CefSettings();
Cef.Initialize(settings);

// Create a browser component
var browser = new ChromiumWebBrowser("https://foxlearn.com");
// Register your Custom Downloads Handler
browser.DownloadHandler = new CustomDownloadHandler();

Once downloads are allowed and initiated, you might want to manipulate or monitor them:

Use the OnBeforeDownloadFired event in your CustomDownloadHandler to get notified before a download starts.

Implement OnDownloadUpdated in your CustomDownloadHandler to track progress or handle completion.

You can control the download behavior in OnBeforeDownload. For instance, you can change the file name, cancel downloads by not calling callback.Continue, or modify the download directory.

If you want to allow downloads and store them automatically in the downloads directory you can modify your code as shown below.

public class CustomDownloadHandler : IDownloadHandler
{
    public event EventHandler<DownloadItem> OnBeforeDownloadFired;

    public event EventHandler<DownloadItem> OnDownloadUpdatedFired;

    public void OnBeforeDownload(IWebBrowser chromiumWebBrowser, IBrowser browser, DownloadItem downloadItem, IBeforeDownloadCallback callback)
    {
        // ...
        OnBeforeDownloadFired?.Invoke(this, downloadItem);

        if (!callback.IsDisposed)
        {
             using (callback)
             {
                  // Define the Downloads Directory Path
                  string downloadsDirectoryPath = "C:\\Users\\FoxLearn\\Downloads\\";                    
                  callback.Continue(Path.Combine(downloadsDirectoryPath, downloadItem.SuggestedFileName), showDialog: false);
             }
        }
    }

    public void OnDownloadUpdated(IBrowser browser, DownloadItem downloadItem, IDownloadItemCallback callback)
    {
        // Handle download progress or completion if needed
    }
}

And that's all you need to do to handle downloads through CefSharp in your project. Once you launch your application and initiate a download from within the embedded Chromium browser, you'll have full control over handling the download process, including specifying where to save the file and monitoring download progress.