Home > Blockchain >  CefSharp doesn't display local PDF file after upgrade to 105.3.390
CefSharp doesn't display local PDF file after upgrade to 105.3.390

Time:10-03

After upgrading CefSharp to Version 105.3.390 the browser doesn't display local pdf files anymore (displaying local html file works).

The browser window is black and Windows OS opens a window: "You'll need a new app to open this chrome-extension link".

As I am using a custom resource handler all urls look like "local://C:/path/to/file.pdf".

Settings:

var cefSettings = new CefSettings()
{
    LogSeverity = LogSeverity.Verbose,
    CachePath = SystemService.CefCacheDir,
    LogFile = SystemService.CefSharpLogFile
};
CefCustomScheme localScheme = new CefCustomScheme
{
    SchemeName = LocalSchemeHandlerFactory.SchemeName,
    SchemeHandlerFactory = new LocalSchemeHandlerFactory(),
    IsCSPBypassing = true
};
cefSettings.RegisterScheme(localScheme);
CefSharp.Cef.Initialize(cefSettings);

LocalSchemeHandlerFactory:

public class LocalSchemeHandlerFactory : ISchemeHandlerFactory
{
    public const string SchemeName = "local";

    public IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request)
    {
        return new CustomSchemeHandler();
    }
}

CustomSchemeHandler:

public class CustomSchemeHandler : ResourceHandler
{
    public override CefReturnValue ProcessRequestAsync(IRequest request, ICallback callback)
    {
        string file = null;
        var uri = new Uri(request.Url);
        if (uri.Scheme == LocalSchemeHandlerFactory.SchemeName || uri.Scheme == SmbSchemeHandlerFactory.SchemeName)
        { 
            if (uri.Scheme == LocalSchemeHandlerFactory.SchemeName)
            {
                var driveInfo = new DriveInfo(uri.Authority);
                var path = uri.LocalPath.Substring(1);
                file = Path.Combine(driveInfo.Name, path);
            }
        }
        else
        {
            // handle invalid scheme
        }

        if (file == null)
            return CefReturnValue.Cancel;

        Task.Run(() =>
        {
            using (callback)
            {
                if (!File.Exists(file))
                {
                    callback.Cancel();
                    return;
                }

                byte[] bytes = File.ReadAllBytes(file);

                var stream = bytes != null ? new MemoryStream(bytes) : null;
                if (stream == null)
                {
                    callback.Cancel();
                }
                else
                {
                    stream.Position = 0;
                    ResponseLength = stream.Length;

                    var fileExtension = Path.GetExtension(file);
                    MimeType = GetMimeType(fileExtension); // application/pdf
                    StatusCode = (int)HttpStatusCode.OK;
                    Stream = stream;

                    callback.Continue();
                }
            }
        });

        return CefReturnValue.ContinueAsync;
    }
}

You find the cef log here.

What am I missing?

UPDATE: Similar to this, when trying to open dev tools in CefSharp, a window opens: "You'll need a new app to open this dev-tools link".

CodePudding user response:

I found it myself. The reason was an implementation of RequestHandler:

internal class BrowserRequestHandler : RequestHandler
{
    protected override bool OnBeforeBrowse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool userGesture, bool isRedirect)
    {
        // delegate all none local URL to OS default browser
        if (!request.Url.StartsWith("file:") && 
            !request.Url.StartsWith(LocalSchemeHandlerFactory.SchemeName))
        {
            Process.Start(request.Url);
            return true;
        }

        return false;
    }
}

But, when opening a PDF file, an additional URL is called: chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/index.html (why?).

Following the logic above, this is handled by the OS which causes opening a window: "You'll need a new app to open this chrome-extension link".

After extending the if statement everything works fine:

        if (!request.Url.StartsWith("chrome-extension") &&
            !request.Url.StartsWith("file:") && 
            !request.Url.StartsWith(LocalSchemeHandlerFactory.SchemeName))
  • Related