I have an application using TWebBrowser component to allow viewing of Adobe PDF documents within the application. This approach is really pretty simple: when a user of the application has Adobe Reader (/Acrobat) installed, by default any PDF documents will get open inside Internet Explorer (and therefore inside TWebBrowser) – neat and simple way to provide easy PDF preview in a Delphi application (until you go 64-bit…).
Another approach would be to directly use Reader’s ActiveX and place it in a container on a form. This approach requires knowing the name of the ActiveX (“acropdf.dll” or alike) and either creating a component out of it (to be drag-dropped to a form) or instantiating the object dynamically.
All this works without any issues as long as you compile your Delphi application as WIN32 (x86) applications – those can work both on x86 and x64 Windows.
Moving to x64
The time has come for this application to be upgraded from 32-bit to 64-bit.
The task of adding WIN64 build type was really simple (Delphi has this feature from XE2 version) – just added a target platform (64-bit Windows) and recompiled – pure 64-bit version ready!
Run the application, all looks good … test the TWebBrowser functionality and … bam!
PDFs no longer open in TWebBrowser!
Rather, Adobe Reader gets started and the PDF loads outside of the application – not something I would expect.
Even worse: for some users only a black “x” and an empty page appear inside the WebBrowser control.
For some other users a more tricky dialog gets displayed:
For some other users all works as expected!
x86 vs x64 vs ActiveX, DLLs and the Rest
What happened here is related to the following: 64-bit Windows is capable of running both 64-bit and 32-bit applications. This is, of course, why my 32-bit application was running without any issues on 64-bit Windows. If the application uses any external DLLs or ActiveX components (as here is the case: TWebBrowser using Reader’s ActiveX plug-in to display PDFs) all those external libraries must also be 32-bit compiled. Again, since 64-bit Windows will run both 32-bit and 64-bit applications – all is working.
However, when you compile a true 64-bit Delphi application, if you are using any external DLLs – all those should also be 64-bit. If your application process is running in a 64-bit address space, the ActiveX/DLL’s address space must match.
There’s a lot of info about this topic available on the Internet so I won’t go into more details here.
Issues With Adobe Reader Versions and TWebBrowser
So what’s happening? Why is the 64-bit version of my application running without any issues for some users and runs with issues (does not, better to say) for others?
All the problems above are related to the version of Adobe Reader my users have on their 64-bit Windows!
Until version 11.0.7 Adobe Reader ActiveX control used to handle PDF documents display in Internet Explorer (and therefore TWebBrowser) was available only as a 32-bit version. Since 32-bit add-ons cannot be loaded in 64-bit process (IE) the PDF does not get loaded with “weird” side-results (mentioned above).
Version 11.0.7 introduces 64-bit add-on and users having this version installed will see no problems – a PDF document will load up inside the TWebBrowser as the plug-in being used is 64-bit!
If you browse the following location “C:\Program Files (x86)\Common Files\Adobe\Acrobat\ActiveX” you will see two DLLs used: “AcroPDF.dll” and “AcroPDF64.dll” – where the latter is obviously the 64-bit.
So all should be fine, but I still had one problem to solve…
The IE’s EPM mode dialog above is what also hit me. I was not sure how to fix this one as I have Reader 11.0.10 installed (latest version of it when this post was written) – therefore 64-bit plug-in available for IE. IE’s EPM mode was disabled, yet the problem was here.
After a few stressy hours I’ve finally located and fixed the issue. The thing is that I also have Adobe Acrobat PRO installed (version X) – this one is 32-bit. IE was using Acrobat to handle PDF display. Had to change this by going to Adobe Acrobat, Edit – Preferences – General.
Select Adobe Reader XI as the default PDF handler in a web browser. Apply. Start the application (64-bit), navigate to a PDF in a TWebBrowser – everything works as expected, finally!
Go or No Go?
To summarize: if you have an application using the WebBrowser control to display PDF documents you (users of your application) first need to have Adobe Reader or Adobe Acrobat (or other software like FoxIt providing IE add-on) installed.
If you build a 32-bit version of your application – everything should work as expected.
If you build a 64-bit version of your application – users would need to have at least Adobe Reader XI (11.0.7) version and everything should work as expected.
If you have both 32-bit (Acrobat X) and 64-bit (Reader XI) – make sure the latter is the one handing PDF display in your 64-bit Delphi application using TWebBrowser.
There’s some info on the 11.0.7 version crashing Delphi applications (AcroPDF.PDF class no longer accessible) here: https://forums.adobe.com/thread/1475620.
Check out: http://mozilla.github.io/pdf.js/
@Mike: Interesting, thanks for the link. However, file:/// protocol is not supported.
Why are you not using pdf.js?
Instead of TWebbrowser you could also try to switch to chromium.
+1 for pdf.js and chromium
Works really well and gets around all the PDF plugin issues