wpf 如何在 Web 浏览器控件中显示 PDF 而不是打开 Acrobat Reader

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18054379/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:22:08  来源:igfitidea点击:

How to display PDF in web browser control instead of opening Acrobat Reader

wpfpdfvisual-studio-2012webbrowser-control

提问by ControlPoly

i am using Acrobat Reader 11.0.3 and window 7, Visual studio 2012 and already enabled Acrobat Reader in Manage Addon

我正在使用 Acrobat Reader 11.0.3 和 window 7、Visual Studio 2012 并且已经在 Manage Addon 中启用了 Acrobat Reader

and follow WPF webbrowser opens PDF file in Adobe reader window

并按照WPF webbrowser 在 Adob​​e 阅读器窗口中打开 PDF 文件

still have error after trying two methods

尝试两种方法后仍然有错误

Navigation to the webpage was canceled even if using administrator account to open WPF program

即使使用管理员帐户打开 WPF 程序,网页导航也被取消

private void CheckAndFixWebBrowserRenderingEngine()
        {
            RegistryKey baseRegistryKey = Registry.LocalMachine;
            string renderingEngineSubKeyString = @"SOFTWARE";

            // 64bit operationg systems have another registry path
            if (Environment.Is64BitOperatingSystem)
            {
                renderingEngineSubKeyString += @"\Wow6432Node";
            }

            renderingEngineSubKeyString += @"\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION";

            //var assemblyValueKey = System.IO.Path.GetFileName(App.ResourceAssembly.Location);
            var assemblyValueKey = System.IO.Path.GetFileName(System.Windows.Application.ResourceAssembly.Location);

            var renderingEngingeValue = 9999; // check other values below

            try
            {
                RegistryKey sk1 = baseRegistryKey.CreateSubKey(renderingEngineSubKeyString);

                var value = sk1.GetValue(assemblyValueKey);
                if (value == null || value.ToString() != renderingEngingeValue.ToString())
                {
                    sk1.SetValue(assemblyValueKey, renderingEngingeValue);

                    //LogHandler.Instance.Add(string.Format("Did update webbrowser rendering engine from {0} to 9000.", value == null ? "[missing]" : value));
                }
            }
            catch (Exception ex)
            {
                //LogHandler.Instance.Add("Could not check webbrowser rendering engine in registry.");
                //LogHandler.Instance.Add(ex.ToString(), Logging.LoggingPriorities.Exception);
            }

            /*
            9999 (0x270F) 
            Internet Explorer 9. Webpages are displayed in IE9 Standards mode, regardless of the !DOCTYPE directive.

            9000 (0x2328) 
            Internet Explorer 9. Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode.

            8888 (0x22B8) 
            Webpages are displayed in IE8 Standards mode, regardless of the !DOCTYPE directive.

            8000 (0x1F40) 
            Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode.

            7000 (0x1B58) 
            Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode.
            */
        }

        public ReportForm()
        {
            this.formID = "Test Report";
            //base.Initialization();
            InitializeComponent();
            CheckAndFixWebBrowserRenderingEngine();

            String PDFPath = @"C:\Users\LAB-User2\Downloads\Elimination_Methods_in_Polynomial_Computer_Alge(Bookos.org).pdf";
            WebBro1.Navigate("file:///" + PDFPath);

Method 2

方法二

i have also tried another method which add reference windowformintegration and use UserControl of winform and it only work in an independent WPF small project when integrate this in my big project, it got above error

我还尝试了另一种方法,它添加了参考 windowformintegration 并使用了 winform 的 UserControl,并且在将其集成到我的大项目中时,它只能在独立的 WPF 小项目中工作,但出现上述错误

String PDFPath = @"C:\Users\LAB-User2\Downloads\Elimination_Methods_in_Polynomial_Computer_Alge(Bookos.org).pdf";
            //WebBro1.Navigate("file:///" + PDFPath);
            webBrowser1.Navigate("file:///" + PDFPath);

private System.Windows.Forms.WebBrowser webBrowser1;
<WindowsFormsHost Margin="1" x:Name="windowsFormsHost1" Height="600" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="1000"/>

var uc = new UserControl1();
            this.windowsFormsHost1.Child = uc;


application.UI.CreateNewForm("Test Report", new Client.Reporting.Pages2.ClientStatement.ReportForm());

public partial class ReportForm : BaseForm

public void CreateNewForm(string title, BaseForm form)
    mw.CreateNewForm(title, form);


public class BaseMainWindow : MetroWindow
    {
        public virtual void CreateNewForm(string title, BaseForm form)
        {

        }

update: it ask to allow block content and grey screen in internet explorer in html file before integrate into big project

更新:在集成到大项目之前,它要求在 html 文件中允许 Internet Explorer 中的块内容和灰屏

<html>
<body>

<object
  classid="clsid:ca8a9780-280d-11cf-a24d-444553540000" id="pdf1" 
  type="application/pdf"
  data="C:\Users\LAB-User2\Downloads\Elimination_Methods_in_Polynomial_Computer_Alge(Bookos.org).pdf"
  style="width: 100%; height: 100%">

<param name="src" "value="C:\Users\LAB-User2\Downloads\Elimination_Methods_in_Polynomial_Computer_Alge(Bookos.org).pdf"></param>

</object>

</body>
</html>

enter image description here

在此处输入图片说明

update: when run your code in big WPF project, it show a red cross enter image description here

更新:在大型 WPF 项目中运行您的代码时,它显示一个红叉 在此处输入图片说明

update : after updated html it works in independent html file, however integrated in WPF big project, it failed to show and only show a red cross

更新 : 更新后的 html 它在独立的 html 文件中工作,但是集成在 WPF 大项目中,它无法显示,只显示一个红叉

String temphtml = "<!-- saved from url=(0016)http://localhost --><body style=\"border: 0; margin: 0; padding: 0\"><object classid=\"clsid:ca8a9780-280d-11cf-a24d-444553540000\" id=\"pdf1\"  type=\"application/pdf\" data=\"02_LAB_LeaveApplication.pdf\" style=\"width: 100%; height: 100%; border: 0; margin: 0; padding: 0\"></object><script>window.onload = function(){ window.focus();pdf1.setActive(); }</script></body>";
            System.IO.File.WriteAllText(@"C:\Users\LAB-User2\Desktop\vpfs-ivpfs-client\iVPFS_Client\Application\bin\Debug\a.html", temphtml);            
            this.WebBro1.Navigate(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "a.html"));

update though running the project downloaded from the codeproject, it show an error and then can show pdf and have a few times blank when open, then i copy codes and library to a a small WPF project and run, it also have error come out and only show white blank https://docs.google.com/file/d/0Bxs_ao6uuBDUeV8yREVBOExSbW8/edit?usp=sharing

更新虽然运行从codeproject下载的项目,它显示一个错误然后可以显示pdf并且打开时有几次空白,然后我将代码和库复制到一个小的WPF项目并运行,它也有错误出来并且只有显示白色空白https://docs.google.com/file/d/0Bxs_ao6uuBDUeV8yREVBOExSbW8/edit?usp=sharing

回答by noseratio

You could generate a temp HTML file to embed the desired PDF:

您可以生成一个临时 HTML 文件来嵌入所需的 PDF:

<body>

<object
  classid="clsid:ca8a9780-280d-11cf-a24d-444553540000" id="pdf1" 
  type="application/pdf"
  data="test.pdf"
  style="width: 100%; height: 100%">

<param name="src" "value"="test.pdf"></param>

</object>

</body>

What's interesting, to make it work with a local (file://) PDF document, I had to specify both dataattribute and srcparam. When it was served via http from localhost, the dataalone was just enough.

有趣的是,要使其与本地(file://)PDF 文档一起使用,我必须同时指定data属性和src参数。当它通过来自 localhost 的 http 提供时,仅数据就足够了。

UPDATE: I could not tell why this doesn't work for the OP, so I've cooked up a very basic C# WebBrowser projectdemo'ing this. It works quite reliably in my environment (Win8, IE10, Acrobat Reader 11.0.3).

更新:我不知道为什么这对 OP 不起作用,所以我编写了一个非常基本的C# WebBrowser 项目演示。它在我的环境(Win8、IE10、Acrobat Reader 11.0.3)中非常可靠地工作。

UPDATE: I think I understand why this is happening. Your project uses WPF, while my sample uses Winforms. Sorry, I did not notice this in the first place. WPF WebBrowser has a different security model, it runs in IE Protected Mode by default.

更新:我想我明白为什么会这样。您的项目使用 WPF,而我的示例使用 Winforms。抱歉,我一开始没有注意到这一点。WPF WebBrowser 具有不同的安全模型,它默认在 IE 保护模式下运行。

With WPF WebBrowser, I've managed to get rid of the prompt (note <!-- saved from url=(0016)http://localhost -->), but I do confirm the Acrobat Reader control just hangs loading the file every now and then:

使用 WPF WebBrowser,我设法摆脱了提示(注意<!-- saved from url=(0016)http://localhost -->),但我确实确认 Acrobat Reader 控件只是时不时地挂起加载文件:

<!-- saved from url=(0016)http://localhost -->

<body style="border: 0; margin: 0; padding: 0">

<object
  classid="clsid:ca8a9780-280d-11cf-a24d-444553540000" id="pdf1" 
  style="width: 100%; height: 100%; border: 0; margin: 0; padding: 0">

  <param name="src" "value"="test.pdf"></param>

</object>

<script>
window.onload = function()
{
  window.focus();
  pdf1.setActive(); 
}
</script>

</body>

Acrobat Reader control is knownto have issues with Protected Mode. Rather than trying to find a workaround for this, it may be easier to host Acrobat Reader ActiveX control directly in your WPF project. Here's how it can be done:

已知Acrobat Reader 控件存在保护模式问题。与其尝试为此寻找解决方法,不如直接在 WPF 项目中托管 Acrobat Reader ActiveX 控件可能更容易。这是如何做到的:

http://www.codeproject.com/Articles/380019/Using-Adobe-Reader-in-a-WPF-apphttp://hugeonion.com/2009/04/06/displaying-a-pdf-file-within-a-wpf-application/

http://www.codeproject.com/Articles/380019/Using-Adobe-Reader-in-a-WPF-app http://hugeonion.com/2009/04/06/displaying-a-pdf-file-within -a-wpf-应用程序/