如何打开一个同时也是项目资源的PDF文件?

9
我有一个PDF文件,已将其导入到我的项目中作为资源。该文件是帮助文档,因此我希望能够在每次部署时都包含它。我希望能够在单击按钮时打开此文件。
我已将生成操作设置为“嵌入资源”。所以现在我想要能够打开它。但是,当我尝试访问资源-My.Resources.HelpFile-时,它是一个字节数组。如果我“知道”最终用户有适合打开PDF文档的程序,我该如何打开它?
如果我错过了以前的问题,请指向正确的方向。我发现了几个关于在应用程序内部打开PDF的问题,但我不在乎Adobe Reader是否单独打开。
8个回答

16

查看这个,轻松从资源中打开PDF文件。

private void btnHelp_Click(object sender, EventArgs e)
    {            
        String openPDFFile = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\HelpDoc.pdf";//PDF DOc name
        System.IO.File.WriteAllBytes(openPDFFile, global::ProjectName.Properties.Resources.resourcePdfFileName);//the resource automatically creates            
        System.Diagnostics.Process.Start(openPDFFile);             
    }   

+1 惊讶于没有人评论这个。我经常使用嵌入式PDF来实现只有一个可执行文件的效果。 - Michael Mankus
对我也起作用了。在分发不需要安装程序将帮助文件复制到本地驱动器的UserControls时,这是一个有用的解决方案。我所做的唯一更改是使用Environment.GetEnvironmentVariable()方法获取当前用户的TEMP文件夹的详细信息。 - IsolatedStorage
1
我觉得这是这个问题的正确答案。不过,我要补充一点,建议使用系统路径,例如String openPDFFile = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\fileName.pdf",而不是那个openPDFFile路径。 - Luís Gonçalves

6
创建一个新的进程:
string path = Path.Combine(Directory.GetCurrentDirectory(), "PDF-FILE.pdf");
Process P = new Process {
    StartInfo = {FileName = "AcroRd32.exe", Arguments = path}
};
P.Start();

为了使这个工作起来,需要将 Visual Studio 设置中的 复制到输出目录 设置为 始终复制,以便于 PDF 文件的复制。

我该如何从这里访问我的资源文件?我不知道用户将在哪里安装我的应用程序,因此我不确定文件将在哪里。对不起,我投了反对票,因为您最初只向我展示了如何打开新的Adobe Reader进程。 - Adam Beck
问题不是关于启动阅读器,而是关于如何向其提供资源。 - mfeingold
@mfeingold 和 @Adam,这是我所做的:将 PDF 添加到 VS2010 项目中,将 Build Action 设置为 嵌入式资源,将 Copy to Output Directory 设置为 始终复制... 然后我就得到了一个可以轻松用上述代码打开的文档。因此,我认为它很好地回答了问题,除非要求 PDF 不能作为程序目录中的文件可用。 - Adam
我仍然收到“打开此文档时出错。找不到该文件”的错误提示。我已经按照您刚才提到的一切做了。 - Adam Beck
请使用以下代码:Arguments = Path.Combine(Directory.GetCurrentDirectory(), "你的文件名") - Adam

2
如果PDF文件的唯一目的是要被PDF阅读器打开,那么不要将它嵌入到资源中。相反,让安装程序将其复制到一个合理的位置(比如EXE文件所在的位置),然后从那里运行它。没必要一遍又一遍地复制它。

然后你只需在应用程序中放置一个链接,并且每次想让用户阅读它时从服务器打开它。 - zmbq

1
"ReferenceGuide"是我添加到资源中的PDF文件的名称。
using System.IO;
using System.Diagnostics;

    private void OpenPdfButtonClick(object sender, EventArgs e)
    {
        //Convert The resource Data into Byte[] 
        byte[] PDF = Properties.Resources.ReferenceGuide;

        MemoryStream ms = new MemoryStream(PDF);

        //Create PDF File From Binary of resources folders helpFile.pdf
        FileStream f = new FileStream("helpFile.pdf", FileMode.OpenOrCreate);

        //Write Bytes into Our Created helpFile.pdf
        ms.WriteTo(f);
        f.Close();
        ms.Close();

        // Finally Show the Created PDF from resources 
        Process.Start("helpFile.pdf");
    }

0

您需要将资源转换为可供程序消耗的格式。

一种方法是将资源内容写入文件(临时文件),然后启动程序并指向该文件。

能否直接将资源提供给程序取决于程序。我不确定Adobe Reader是否可以这样做。

要将资源内容写入文件,您可以创建MemoryStream类的实例,并将字节数组传递给其构造函数。


0
File.Create("temp path");
File.WriteAllBytes("temp path", Resource.PDFFile)

0
这应该会有所帮助 - 我经常使用这段代码来打开各种可执行文件、文档等,它们都被嵌入为资源。
private void button1_Click(object sender, EventArgs e)
   {
    string openPDFfile =  @"c:\temp\pdfName.pdf";
    ExtractResource("WindowsFormsApplication1.pdfName.pdf", openPDFfile);
    Process.Start(openPDFfile);
   }

     void ExtractResource( string resource, string path )
            {
                Stream stream = GetType().Assembly.GetManifestResourceStream( resource );
                byte[] bytes = new byte[(int)stream.Length];
                stream.Read( bytes, 0, bytes.Length );
                File.WriteAllBytes( path, bytes );
            }

enter image description here


需要命名空间 - 已编辑上面的代码并附上了屏幕截图。现在可以正常工作了...希望能帮到你 :) - Dan Ergis

0
//create a temporal file
string file = Path.GetTempFileName() + ".pdf";
//write to file
File.WriteAllBytes(file, Properties.Resources.PDF_DOCUMENT);
//open with default viewer
System.Diagnostics.Process.Start(file);

1
虽然这段代码可能回答了问题,但提供有关它如何以及/或为什么解决问题的附加上下文将改善答案的长期价值。 - shaunakde
1
我认为这段代码完美地回答了问题,不需要额外的上下文。 - user5583316

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接