25

I'm just creating a simple calculator in C# (windows form)

I've created a "User Help" which is a pdf file, what I want is to display that pdf file if the user clicks on the "Help" button in the WinForm. If assumed that Adobe reader is pre-installed on the user's machine....

How to open the pdf file on button click in winForm?

I don't plan to provide this pdf file on hard disk of user. Which means that I have to embed this pdf into the calculator (winForm) and have to display it on the button click.

Kindly guide me with the best practise for displaying an embedded file in winForm.

gsvirdi
  • 406
  • 2
  • 7
  • 22
  • Why don't you want to have the pdf as a separate file? – SurDin Feb 08 '10 at 08:05
  • Bcoz if u take "distribution" in cosideration, then developing a utility should not be in pieces. Just the exe file (without installaion) will work perfectly as a simple "Calculator", providing pieces of files with it is not a good practise I believe. U can correct me if I'm wrong. – gsvirdi Feb 08 '10 at 08:52

11 Answers11

23

You can reference the Adobe Reader ActiveX control and bundle it with your application.

Simply add AcroPDF.PDF.1 to your Toolbox from the COM Components tab (right click toolbox and click Choose Items...) then drag an instance onto your Winform to have the designer create the code for you. Alternately, after adding the necessary reference you can use the following code:

AxAcroPDFLib.AxAcroPDF pdf = new AxAcroPDFLib.AxAcroPDF();
pdf.Dock = System.Windows.Forms.DockStyle.Fill;
pdf.Enabled = true;
pdf.Location = new System.Drawing.Point(0, 0);
pdf.Name = "pdfReader";
pdf.OcxState = ((System.Windows.Forms.AxHost.State)(new System.ComponentModel.ComponentResourceManager(typeof(ViewerWindow)).GetObject("pdfReader.OcxState")));
pdf.TabIndex = 1;

// Add pdf viewer to current form        
this.Controls.Add(pdf);

pdf.LoadFile(@"C:\MyPDF.pdf");
pdf.setView("Fit");
pdf.Visible = true;
Winston Smith
  • 21,585
  • 10
  • 60
  • 75
  • 5
    not very nice if your users has chosen to use a 3rd party control to read pdf documents. – Ian Ringrose Feb 08 '10 at 14:05
  • @Ian Are you suggesting that a *WinForms Calculator Application* should inherit configuration from IE on the same machine? I hope not. – Winston Smith Feb 08 '10 at 15:55
  • deos the Adobe Reader ActiveX control work with "register free com", or will a user need to install it? – Ian Ringrose Feb 08 '10 at 15:55
  • 1
    @Winsten, No but it should not change the PDF reader that IE/Firefox has been setup to use, installing Adober reader when the app is installed may change all sorts of settings (knowing Adobe!) – Ian Ringrose Feb 08 '10 at 15:58
  • @Ian - The users settings certainly **will not** be changed, nor will Adobe reader be installed. This approach simply means bundling two DLLs with your application (`AxInterop.AcroPDFLib.dll` and `Interop.AcroPDFLib.dll`) which it uses to display the PDF. – Winston Smith Feb 08 '10 at 17:06
  • 1
    @WinstonSmith where can I find these two DLLs ?? I didn't find them in COM Tab and I didn't find them in Adobe folder ?! any suggestions?? – Ahmad Hajjar Jan 11 '12 at 12:12
11

You could use the WebBrowser control and let IE load a PDF reader for you if there is one installed on the machine.

However the last time I tried this, I had to write the PDF file to disk first, so I could point the WebBrowser control at it.

Dan McGrath
  • 41,220
  • 11
  • 99
  • 130
Ian Ringrose
  • 51,220
  • 55
  • 213
  • 317
  • 3
    Not very nice if your users prefer Firefox ;-) – Winston Smith Feb 08 '10 at 15:50
  • 1
    @Winston, as the WebBroser control does not have the IE toolbars, if you disabled the right click menu most users will not be able to tell it is IE. – Ian Ringrose Feb 08 '10 at 15:54
  • This sounds simple...... So how u did it? I think to achieve this I would need to bundle the file with the application. Then on "Button click" event the application (.exe) should check with>>> if (File.Exists("user manual.pdf")) // then display else //extract the pdf to the same directory. //and then display it in the browser. I know about "add an existing item as reference, but how to copy it to the output directory via C# code? – gsvirdi Feb 09 '10 at 11:28
9

I would put it on within my program folder, add a link within my Start Menu folder to allow a direct access (without starting my tool) and just at on some click event System.Diagnostics.Process.Start(@".\Manual.pdf");

Update

Ok, now we come to a completely new question: How to embed a file in my application and start it?

For this question you'll find already several answers here, but here is the short version:

  1. Right click your project and select Add - Existing Item
  2. Select your file (don't double click it)
    • Click the little arrow next to the Add button and select Add As Link
  3. Double click on Properties - Resources.resx
  4. Click the little arrow next to Add Resource and select Add Existing File
  5. Select the same file again in the open dialog
  6. Now you can access the file within your code as byte[] from Properties.Resources.NameOfResource

With these steps you reference your file where ever it exists within your structure. If you like that a copy of your pdf file will be put into a subfolder Resources within your project, just skip the points one and two in the above list.

To get your pdf now opened, you'll have to write the byte[] down to disk (maybe with Path.GetTempFileName()) and start it with Adobe Reader. (Don't forget to delete the file after usage)

Oliver
  • 43,366
  • 8
  • 94
  • 151
  • I agree that the Process method works perfetly. Process.Start("C:\\Documents and Settings\\gsv\\Desktop\\manual.pdf"); But as I said... in that case I will need to provide a separate pdf file with this calculator.exe Is it possible to embed the file into the exe itself??? – gsvirdi Feb 08 '10 at 08:55
9

If you want to display a pdf inside your application, the WebBrowser control is probably preferable over the Adobe Reader control, as it will open the file very smoothly in PDF Reader or whatever IE is using as a default to open pdfs. You simply add the WebBrowser control to an existing or new form and navigate to the pdf file.

Never assume that a user has Adobe or any other third party controls or libraries installed on their machines, always package them with your executable or you may have problems.

The Adobe Reader control obviously doesn't integrate as well with .NET as an intrinsic Windows component. As a rule, I always favor the use of built in .Net controls over third party vendors. As far as embedding the file in the actual executable; not going to happen until Microsoft decides any old PDF can be worked into the CLS and compiled into MSIL. What you have when you develop any app in .NET is code that can be compiled into intermediate MSIL to be translated at runtime by the CLR into native code and executed in the OS.

WebBrowser1.Navigate("SomePDF.pdf");
Scott Net
  • 219
  • 4
  • 2
8

There is a C# pdf viewer project on google code. http://code.google.com/p/pdfviewer-win32/ there is the viewer and there is the library that it uses available that uses mupdf and xpdf to render the pdf documents in your winforms program. I am currently developing a User control library for people to use and drop into their programs for pdf viewing capabilities. it works pretty good.

Cory
  • 513
  • 5
  • 14
6

If your user has Adobe Reader (or any other PDF reader) installed on their machine, you could use:

System.Diagnostics.Process.Start(
       "My-PDF-file.pdf");

Hope this helps.

Note: Obviously, this will fail if the user does not have any PDF Reader applications installed.

Tommy
  • 172
  • 9
  • I agree that the Process method works perfetly. Process.Start("C:\\Documents and Settings\\gsv\\Desktop\\manual.pdf"); But as I said... in this case I will need to provide a separate pdf file with this calculator.exe!!!! Is it possible to embed the file into the exe itself??? Then on "Button_Click" event the application can extract the pdf into the same folder and then display it? How to extract the file into the same user's directory? – gsvirdi Feb 10 '10 at 04:28
  • 1
    Ah, yes - this is possible. But since I couldn't get it working properly, I wouldn't recommend it. – Tommy Feb 10 '10 at 08:33
5

I would suggest converting your pdf file to a Microsoft help file, so that you don't need to have Adobe Reader installed (it's buggy, and has way too much security issues). You cannot expect users to have this.

In reply to the starter's comment:

Yes you would need to create your help file as an HTML document instead of a pdf. There is no easy way to convert pdf to HTML.

Anemoia
  • 7,928
  • 7
  • 46
  • 71
  • Hmmmmmm.... I do agree with u that I can't expect users to have pdf reader installed, but bcoz I'm just a learner so this simple "calculater utility" is not expected to be widely spread (popular) application. I'm just learning to code. .... I had just installed Microsoft help file creator also but I'm not able to use it easily. Its asking for html files (input). I think I need to carefully see everything inside this help file creator. – gsvirdi Feb 08 '10 at 07:43
4

Getting the embedded file out should not be a problem at all. This is not dependent on it being .pdf format, and you can just look for a separate solution there.

For display, unless you know Acrobat or similar is installed (well, even Edge can open those files nowadays), or if you want to display the file embedded in a WinForms application, there is

Codeproject Solution

https://www.codeproject.com/Articles/37458/PDF-Viewer-Control-Without-Acrobat-Reader-Installe

written in VB relying on lots of (partially commercial, if your solution is commercial) libraries.

PdfiumViewer

https://github.com/pvginkel/PdfiumViewer

is great and also available via NuGet.

The PdfiumViewer library primarily consists out of three components:
•The  PdfViewer  control. This control provides a host for the  PdfRenderer  control and has a default toolbar with limited functionality;
•The  PdfRenderer  control. This control implements the raw PDF renderer. This control displays a PDF document, provides zooming and scrolling functionality and exposes methods to perform more advanced actions;
•The  PdfDocument  class provides access to the PDF document and wraps the Pdfium library.

It is an all-in-one solution for display and comes with a friendlier Apache 2.0 license.

edit, added sample code, for your convenience :) I included the following

data = File.ReadAllBytes(@"C:\temp\abc.pdf");
PdfiumViewer.PdfDocument doc;
using (Stream stream = new MemoryStream(data))
{
    doc = PdfiumViewer.PdfDocument.Load(stream);
    var viewer = new PdfiumViewer.PdfViewer();
    viewer.Document = doc;
    var form = new System.Windows.Forms.Form();
    form.Size = new Size(600, 800);
    viewer.Dock = System.Windows.Forms.DockStyle.Fill;
    form.Controls.Add(viewer);
    form.ShowDialog();
}

This generates a form on the fly, of course you could also use the designer.

Andreas Reiff
  • 7,961
  • 10
  • 50
  • 104
3

It might be possible to embed Adobe's Reader in your form as an ActiveX component. But that means you'll have to make sure Reader is installed on the client machine for that to work.

In case it doesn't have to be strictly embedded you can just launch the PDF file and let whatever viewer the user has open it.

Assaf Lavie
  • 73,079
  • 34
  • 148
  • 203
  • Even if Adobe reader is not installed I think we can take care of this case with the Try {} catch {} thing and Pop a message in case the reader is not there. No worries. The only thing I'm wondering is the use of "Embedding" a file into the exe and displaying it without providing it on the user's hard disk as a separate file. – gsvirdi Feb 08 '10 at 08:57
2

How to open PDF file with relative path

In this case the created Application has to run on several PC´s. To reference on a file which is not in the network, but in the Programm Folder itself, use the following code Snippet:

First of all include the following Library:

using System.IO;

Then use a Button, picturebox, or whatever to create a ClickEvent and use the following code snippet:

    private void pictureBox2_Click(object sender, EventArgs e)
    {
        //get current folderpath of the .exe
        string ProgramPath = AppDomain.CurrentDomain.BaseDirectory;
        //jump back relative to the .exe-Path to the Resources Path
        string FileName = string.Format("{0}Resources\\Master_Thesis_Expose.pdf", Path.GetFullPath(Path.Combine(ProgramPath, @"..\..\")));

        //Open PDF
        System.Diagnostics.Process.Start(@"" + FileName + "");

    }

|Thumb up|

Ricardo Fercher
  • 917
  • 6
  • 10
-2
AxAcroPDF1.LoadFile("C:ShippingForm.pdf")
AxAcroPDF1.src = "C:ShippingForm.pdf"
AxAcroPDF1.setShowToolbar(False)
AxAcroPDF1.setView("fitH")
AxAcroPDF1.setLayoutMode("SinglePage")
AxAcroPDF1.setShowScrollbars(False)
AxAcroPDF1.Show()
Tharif
  • 13,794
  • 9
  • 55
  • 77
  • 3
    This is not a very useful answer; you are missing several critical steps for making it work. – Cody Gray - on strike Apr 30 '15 at 06:15
  • 2
    Hiya there, while this may well answer the question, please be aware that other users might not be as knowledgeable as you. Why don't you add a little explanation as to why this code works? Thanks! – Vogel612 Apr 30 '15 at 08:44