使用 CefSharp 显示本地 PDF 文件

Display a local PDF file with CefSharp

我正在尝试使用从文件中读取内存流的自定义 LocalSchemeHandler 显示本地 pdf 文件。

文件存在,正在正确读取内存流。但是浏览器中没有显示任何内容 window。通过 文件方案 显示相同的文件有效。

资源处理器:

public class LocalSchemeHandler : ResourceHandler
{
    public override bool ProcessRequestAsync(IRequest request, ICallback callback)
    {
        var uri = new Uri(request.Url);
        var file = uri.AbsolutePath;

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

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

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

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

                    callback.Continue();
                }
            }
        });

        return true;
    }
}

ISchemeHandlerFactory:

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

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

设置:

var settings = new CefSettings();
settings.RegisterScheme(new CefCustomScheme
{
    SchemeName = CustomProtocolSchemeHandlerFactory.SchemeName,
    SchemeHandlerFactory = new CustomProtocolSchemeHandlerFactory()
});
// Increase the log severity so CEF outputs detailed information, useful for debugging
settings.LogSeverity = LogSeverity.Default;
Cef.Initialize(settings);

编辑 尝试通过 ResourceHandler.FromFilePath 显示 PDF 文件也不起作用(未显示任何内容)。

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

    public IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request)
    {
        var uri = new Uri(request.Url);
        var file = uri.AbsolutePath;

        var fileExtension = Path.GetExtension(file);
        var mimeType = ResourceHandler.GetMimeType(fileExtension);
        return ResourceHandler.FromFilePath(file, mimeType);
    }
}

EDIT2

将 LogSeverity 设置为默认值后,日志显示:[0524/150955.108:INFO:CONSOLE(20)] "Refused to load plugin data from 'local://c/Users/abidh/Desktop/pdf.pdf' because it violates the following Content Security Policy directive: "object-src * blob: externalfile: file: filesystem: data:".

未找到使用 google 的解决方案。感谢amaitland,使用IsCSPBypassing属性解决了问题:

var settings = new CefSettings();
settings.RegisterScheme(new CefCustomScheme
{
    SchemeName = CustomProtocolSchemeHandlerFactory.SchemeName,
    SchemeHandlerFactory = new CustomProtocolSchemeHandlerFactory(),
    IsCSPBypassing = true
});
settings.LogSeverity = LogSeverity.Error;
Cef.Initialize(settings);

将 PDF 文件路径设置为 ChromiumWebBrowser.Address,格式如 file:///C:/Users/xxx/yyy.pdf,CEFSharp 将像 Chrome 浏览器一样呈现 PDF。