9

I have a PDF file that I have imported in as a resource into my project. The file is a help document so I want to be able to include it with every deployment. I want to be able to open this file at the click of a button.

I have set the build action to "Embedd Resource". So now I want to be able to open it. However, When I try accessing the resource - My.Resources.HelpFile - it is a byte array. How would I go about opening this if I know that the end-user has a program suitable to opening PDF documents?

If I missed a previous question please point me to the right direction. I have found several questions about opening a PDF within an application, but I don't care if Adobe Reader opens seperately.

Adam Beck
  • 1,271
  • 2
  • 14
  • 25

8 Answers8

16

Check this out easy to open pdf file from resource.

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);             
    }   
M2K SOFT
  • 169
  • 1
  • 2
  • +1 Surprised no one commented on this. I do this all the time with embedded PDFs so that I can still have just a single executable. – Michael Mankus Sep 10 '12 at 14:44
  • Worked for me too. When distributing UserControls where there is no need for an installer to copy help files to the local drive, this is a useful solution. The only change I made was using the Environment.GetEnvironmentVariable() method to get the details of the TEMP folder for the current user. – IsolatedStorage Mar 24 '15 at 05:09
  • 1
    I feel like this is the correct answer for this question. I'd add however that instead of that `openPDFFile `path, use a system path like `String openPDFFile = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\fileName.pdf"` for example – Luís Gonçalves Mar 07 '17 at 11:09
6

Create a new Process:

string path = Path.Combine(Directory.GetCurrentDirectory(), "PDF-FILE.pdf");
Process P = new Process {
    StartInfo = {FileName = "AcroRd32.exe", Arguments = path}
};
P.Start();

In order for this to work, the Visual Studio setting Copy to Output Directory has to be set to Copy Always for the PDF file.

Adam
  • 15,537
  • 2
  • 42
  • 63
  • How would I access my resource file from this? I do not know where the user is going to install my application so I am not for sure where the file is going to be. And sorry, I downvoted because you originally only showed me how to open a new Adobe Reader process. – Adam Beck Dec 22 '11 at 20:49
  • The questions was not about launching the reader, but rather about feeding it the resource – mfeingold Dec 22 '11 at 20:51
  • @mfeingold and @Adam Here's what I did: Added PDF to VS2010 project, set `Build Action` to `embedded resource`, set `Copy to Output Directory` to `Copy Always` ... and I end up with a document I can easily open with the code above. So I think it addresses the question pretty well, unless it is a requirement that the PDF may *not* be available as a file in the program's directory. – Adam Dec 22 '11 at 20:58
  • I'm still getting a "There was an error opening this document. This file cannot be found". I did everything you just mentioned. – Adam Beck Dec 22 '11 at 21:04
  • use `Arguments = Path.Combine(Directory.GetCurrentDirectory(), "YOUR FILE NAME")` – Adam Dec 22 '11 at 21:06
2

If the only point of the PDF is to be opened by a PDF reader, don't embed it as a resource. Instead, have your installation copy it to a reasonable place (you could put it where the EXE is located), and run it from there. No point in copying it over and over again.

zmbq
  • 38,013
  • 14
  • 101
  • 171
  • Then you just put a link to it in the application, and open it from the server each time you want the user to read it. – zmbq Dec 23 '11 at 07:21
1

"ReferenceGuide" is the name of the pdf file that i added to my resources.

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");
    }
ilmenite
  • 199
  • 1
  • 3
  • 11
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
    While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. – shaunakde Jun 17 '20 at 21:31
  • 1
    I think this code answers the question perfectly, no additional context is needed –  Jun 19 '20 at 09:46
0

You need to convert the resource into format acceptable for the program supposed to consume your file.

One way of doing this is to write the content of the resource to a file (a temp file) and then launch the program pointing it to the file.

Whether it is possible to feed the resource directly into the program depends on the program. I am not sure if it can be done with the Adobe Reader.

To write the resource content to a file you can create an instance of the MemoryStream class and pass your byte array to its constructor

mfeingold
  • 7,094
  • 4
  • 37
  • 43
0

This should help - I use this code frequently to open various executable, documents, etc... which I have embedded as a resource.

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
  • 375
  • 1
  • 5
  • 15
  • It needed the namespace - edited the code above and attached a screenshot. Works fine now...hope it helps :) – Dan Ergis Dec 22 '11 at 22:06
0
File.Create("temp path");
File.WriteAllBytes("temp path", Resource.PDFFile)
Reza ArabQaeni
  • 4,848
  • 27
  • 46