Aprende a manejar las descargas en Cefsharp.

Cómo permitir y manipular descargas en Cefsharp

De forma predeterminada, en tu navegador embebido de Chromium en WinForms usando la biblioteca Cefsharp, si intentas navegar a una página web que le permite descargar un archivo de cualquier tipo, notarás que incluso cuando haces clic en el botón de descarga, no pasa nada . No hay interacción con el navegador sobre dónde guardar el archivo ni se almacena en ningún lugar, no hay progreso de descarga, absolutamente nada.

En este artículo, te explicaré cómo permitir fácilmente descargas en tu propia instancia de Cefsharp en WinForms de 2 formas diferentes.

1. Crea una clase de controlador de descarga personalizada

Necesitas crear una clase de controlador de descarga personalizada. Esta clase se asignará a la propiedad DownloadHandler de la instancia de ChromiumWebBrowser. De acuerdo con tus necesidades y el comportamiento permitido, simplemente puedes iniciar un cuadro de diálogo de
"Guardar como" que le permitirá al usuario personalizar el nombre de archivo de la descarga donde el usuario lo desee. La otra opción es almacenar automáticamente los archivos en el directorio de Descargas del sistema.

1.A. Permitir descargas iniciando el cuadro de diálogo de Guardar como

La primera opción permitirá al usuario seleccionar la ruta donde se descargará el archivo usando el diálogo del sistema. Crea el archivo MyCustomDownloadHandler.cs que contendrá el siguiente código:

using CefSharp;
using System;

namespace CefsharpSandbox
{
    class MyCustomDownloadHandler : 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)
            {
                Console.WriteLine("== File information ========================");
                Console.WriteLine(" File URL: {0}", downloadItem.Url);
                Console.WriteLine(" Suggested FileName: {0}", downloadItem.SuggestedFileName);
                Console.WriteLine(" MimeType: {0}", downloadItem.MimeType);
                Console.WriteLine(" Content Disposition: {0}", downloadItem.ContentDisposition);
                Console.WriteLine(" Total Size: {0}", downloadItem.TotalBytes);
                Console.WriteLine("============================================");
            }

            OnBeforeDownloadFired?.Invoke(this, downloadItem);

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

        /// https://cefsharp.github.io/api/51.0.0/html/T_CefSharp_DownloadItem.htm
        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))
                {
                    Console.WriteLine(
                        "Current Download Speed: {0} bytes ({1}%)",
                        downloadItem.CurrentSpeed,
                        downloadItem.PercentComplete
                    );
                }

                if (downloadItem.IsComplete)
                {
                    Console.WriteLine("The download has been finished !");
                }
            }
        }
    }
}

1.B. Permitir descargas y almacenarlas automáticamente en el directorio de descargas

La segunda opción almacenará automáticamente las descargas que procesa el navegador dentro de un directorio personalizado (generalmente el directorio de Descargas del sistema). Crea el archivo MyCustomDownloadHandler.cs que contendrá el siguiente código:

using CefSharp;
using System;
using System.IO;

namespace CefsharpSandbox
{
    class MyCustomDownloadHandler : 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)
            {
                Console.WriteLine("== File information ========================");
                Console.WriteLine(" File URL: {0}", downloadItem.Url);
                Console.WriteLine(" Suggested FileName: {0}", downloadItem.SuggestedFileName);
                Console.WriteLine(" MimeType: {0}", downloadItem.MimeType);
                Console.WriteLine(" Content Disposition: {0}", downloadItem.ContentDisposition);
                Console.WriteLine(" Total Size: {0}", downloadItem.TotalBytes);
                Console.WriteLine("============================================");
            }

            OnBeforeDownloadFired?.Invoke(this, downloadItem);

            if (!callback.IsDisposed)
            {
                using (callback)
                {
                    // Define the Downloads Directory Path
                    // You can use a different one, in this example we will hard-code it
                    string DownloadsDirectoryPath = "C:\\Users\\sdkca\\Downloads\\";
                    
                    callback.Continue(
                        Path.Combine(
                            DownloadsDirectoryPath, 
                            downloadItem.SuggestedFileName
                        ),
                        showDialog: false
                    );
                }
            }
        }

        /// https://cefsharp.github.io/api/51.0.0/html/T_CefSharp_DownloadItem.htm
        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))
                {
                    Console.WriteLine(
                        "Current Download Speed: {0} bytes ({1}%)",
                        downloadItem.CurrentSpeed,
                        downloadItem.PercentComplete
                    );
                }

                if (downloadItem.IsComplete)
                {
                    Console.WriteLine("The download has been finished !");
                }
            }
        }
    }
}

Como se menciona en el código, codificamos manualmente la ruta del directorio de descargas. Si deseas obtener dinámicamente el directorio de descargas de tu sistema, es posible que desees utilizar un método personalizado que puedes encontrar en este otro artículo.

2. Utiliza la clase de controlador de descargas personalizada como la predeterminada

Ahora necesita simplemente asignar una nueva instancia de la clase creada recientemente a la propiedad DownloadHandler de tu instancia ChromiumWebBrowser en tu código de inicialización de esta manera:

CefSettings settings = new CefSettings();
// Some settings if you have, here
// Initialize cef with the provided settings
Cef.Initialize(settings);

// Create a browser component
ChromiumWebBrowser chromeBrowser = new ChromiumWebBrowser("https://ourcodeworld.com");
// Register your Custom Downloads Handler
chromeBrowser.DownloadHandler = new MyCustomDownloadHandler();

// ...
// Rest of your code
// ...

Y eso es todo lo que necesita hacer para manejar las descargas a través de Cefsharp en tu proyecto. Ahora, si inicias tu aplicación e inicia alguna descarga, encontrarás la siguiente información en la salida de tu consola:

== File information ========================
 File URL: https://somedomain.com/myimage.png
 Suggested FileName: myimage.png
 MimeType: image/png
 Content Disposition: attachment; filename="myimage.png"
 Total Size: 28635
============================================
(Appears only when downloading the file)
Current Download Speed: 28635 bytes (100%)
Current Download Speed: 28635 bytes (100%)
Current Download Speed: 0 bytes (100%)
Current Download Speed: 0 bytes (100%)
The download has been finished !

Que te diviertas ❤️!


Ingeniero de Software Senior en EPAM Anywhere. Interesado en la programación desde los 14 años, Carlos es un programador autodidacta, fundador y autor de la mayoría de los artículos de Our Code World.

Conviertete en un programador más sociable

Patrocinadores