Shubhank
Shubhank

Reputation: 53

can't open pdf with wpf webbrowser

I'm trying to create an app to open a local PDF file using web browser in WPF. However the file doesn't open properly, instead displays a grey blank screen. The code works perfectly fine when used to open a HTML file. Please help!

image

Code: webBrowser1.Navigate(@"file:///C:/Working/sample.pdf");

Note: I have adobe reader installed in my PC, if that is necessary. Is it?

Upvotes: 5

Views: 5711

Answers (2)

Umid Akbaraliyev
Umid Akbaraliyev

Reputation: 29

I'll probably add a few changes to @Mikael's code (In case something didn't work out for you)

public class CustomProtocolSchemeHandler : ResourceHandler
{
    public CustomProtocolSchemeHandler()
    {
    }

    public override CefSharp.CefReturnValue ProcessRequestAsync(IRequest request, ICallback callback)
    {
        return CefSharp.CefReturnValue.Continue;
        
    }
}

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

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

Upvotes: 1

Mikael Koskinen
Mikael Koskinen

Reputation: 12906

WPF by default uses IE-based WebBrowser. In order to be able to view PDF-files, you must have a plugin installed into IE which can display PDF-files.

In addition to grey background, this is what can happen with a PC where IE doesn't have a PDF-plugin (Acrobat Reader etc) installed:

IE WPF PDF without plugin

If you don't want to install plugins, one option to get around this issue is to use Windows 10 APIs to draw the PDF.

Other option is a 3rd party library, like CefSharp. Here's steps for using CefSharp:

First install Nuget CefSharp.WPF

Second, change XAML from the default WebBrowser to:

    <wpf:ChromiumWebBrowser Loaded="ChromiumWebBrowser_Loaded" x:Name="Browser"></wpf:ChromiumWebBrowser>

Then create custom resolvers for CefSharp:

public class CustomProtocolSchemeHandler : ResourceHandler
{
    public CustomProtocolSchemeHandler()
    {
    }

    public override bool ProcessRequestAsync(IRequest request, ICallback callback)
    {
        return true;
    }
}

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

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

Almost lastly, register the resolvers in App.xaml.cs:

public partial class App : Application
{
    protected override void OnLoadCompleted(NavigationEventArgs e)
    {
        var settings = new CefSettings();
        settings.RegisterScheme(new CefCustomScheme
        {
            SchemeName = CustomProtocolSchemeHandlerFactory.SchemeName,
            SchemeHandlerFactory = new CustomProtocolSchemeHandlerFactory(),
            IsCSPBypassing = true
        });

        settings.LogSeverity = LogSeverity.Error;
        Cef.Initialize(settings);
    }
}

Now everything should work:

WPF PDF CefSharp

More information about using CefSharp: https://www.codeproject.com/Articles/881315/Display-HTML-in-WPF-and-CefSharp-Tutorial-Part

Upvotes: 4

Related Questions