Skip to content

Instantly share code, notes, and snippets.

@iamsilvio
Created October 20, 2012 22:46
Show Gist options
  • Save iamsilvio/3925098 to your computer and use it in GitHub Desktop.
Save iamsilvio/3925098 to your computer and use it in GitHub Desktop.
Print PDFs with Adobe Acrobat Reader from c#
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Microsoft.Win32;
namespace skat.Printserver
{
/// <summary>
/// A wrapper around Adobe Acrobat Reader that helps to print PDF files.
/// </summary>
public class PdfFilePrinter
{
#region ctor
/// <summary>
/// Initializes a new instance of the <see cref="PdfFilePrinter"/> class.
/// </summary>
/// <param name="pdfFilePath">File Path of the PDF.</param>
/// <param name="printerName">Name of the printer.</param>
public PdfFilePrinter(string pdfFilePath = "", string printerName = "")
{
if (pdfFilePath != String.Empty)
{
PdfFullFilePath = pdfFilePath;
}
if (printerName != String.Empty)
{
PrinterName = printerName;
}
_adobeReaderPath = GetAcrobatReaderPath();
}
#endregion
#region PDF File Path
private string _pdfFileName;
private string _workingDirectory;
private string _pdfFullFilePath;
/// <summary>
/// Gets or sets the PDF file to print
/// </summary>
public string PdfFullFilePath
{
get { return _pdfFullFilePath; }
set
{
if (!File.Exists(value))
throw new InvalidOperationException(String.Format("The file {0} does not exist.", value));
_pdfFileName = Path.GetFileName(value);
_workingDirectory = Path.GetDirectoryName(value);
_pdfFullFilePath = value;
}
}
#endregion
#region Printer Name
private string _printerName;
/// <summary>
/// Gets or sets the name of the printer.
/// </summary>
/// <value>The name of the printer.</value>
/// <example>'\\myserver\HP LaserJet PCL5'</example>
public string PrinterName
{
get
{
if (String.IsNullOrEmpty(_printerName))
{
PrinterName = "default";
}
return _printerName;
}
set
{
if (_printerName == value) return;
using (var printServer = new System.Printing.LocalPrintServer())
{
var printer = printServer.GetPrintQueues().FirstOrDefault(p => p.FullName == value);
_printerName = printer == null ?
printServer.DefaultPrintQueue.FullName : printer.FullName;
}
}
}
#endregion
#region Print
/// <summary>
/// Prints the PDF file.
/// </summary>
/// <param name="milliseconds">The number of milliseconds to wait for completing the print job.</param>
public void Print(int milliseconds = -1)
{
if (String.IsNullOrEmpty(PdfFullFilePath))
{
throw new NullReferenceException("there is no file to print");
}
GetAcrobatProcess();
var args = String.Format("/t \"{0}\" \"{1}\"", _pdfFileName, PrinterName);
var startInfo = new ProcessStartInfo
{
FileName = _adobeReaderPath,
Arguments = args,
CreateNoWindow = true,
ErrorDialog = false,
UseShellExecute = false,
WorkingDirectory = _workingDirectory
};
var process = Process.Start(startInfo);
if (!process.WaitForExit(milliseconds))
{
process.Kill();
}
}
#endregion
#region GetAcrobatProcess
private static Process _runningAcro;
private void GetAcrobatProcess()
{
if (_runningAcro != null)
{
if (!_runningAcro.HasExited) return;
_runningAcro.Dispose();
_runningAcro = null;
}
var processes = Process.GetProcesses();
_runningAcro = processes.FirstOrDefault(p => p.Modules[0].FileName == _adobeReaderPath);
if (_runningAcro != null) return;
_runningAcro = Process.Start(_adobeReaderPath);
if (_runningAcro != null) _runningAcro.WaitForInputIdle();
}
#endregion
#region Get Acrobat Reader Path
private readonly string _adobeReaderPath;
private static string GetAcrobatReaderPath()
{
const string keyBase = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths";
const string fileName = "AcroRd32.exe";
var localMachine = Registry.LocalMachine;
using (var fileKey = localMachine.OpenSubKey(string.Format(@"{0}\{1}", keyBase, fileName)))
{
if (fileKey != null)
{
return fileKey.GetValue(string.Empty).ToString();
}
}
throw new Exception(string.Format("no installation of {0} found", fileName));
}
#endregion
}
}
@naedisgood
Copy link

Sir, I have adobe reader installed the newest one. I tried using this code and its giving me error on the adobe reader path saying Access denied. Can you help me?

@iamsilvio
Copy link
Author

Wow, you really dug up some old source code of mine.
You have two options

  1. run it as Admin
  2. set permissions for your user on the reg path

@naedisgood
Copy link

Haha. I am new, How am I going to do the "set permissions for your user on the reg path"? >.<

I ran as admin still access denied.

@Ncmarteitpi
Copy link

Hi is this applicable for .NET 6.0? I try to recreate it but it says that System.Printing.LocalPrintServer does not exist in the namespace System
.

@iamsilvio
Copy link
Author

Hi is this applicable for .NET 6.0? I try to recreate it but it says that System.Printing.LocalPrintServer does not exist in the namespace System
.

the code is 11 years old, this is .net 4 stuff
please look at the date
in 2012 there was not even a thought of .net 6 or core

@Ncmarteitpi
Copy link

I see, do you have any idea in silent printing ? I am also a beginner and I want to learn how to do silent printing, do you have any idea regarding that ? thank you so much !!

@iamsilvio
Copy link
Author

have a look at iTextsharp if it has to be C#

using System;
using System.Drawing.Printing;
using iText.Kernel.Pdf;
using iText.Kernel.Print;

namespace PdfPrintingExample
{
    class Program
    {
        static void Main(string[] args)
        {
            string pdfPath = "path/to/your/pdf.pdf";

            // Create a PdfDocument object
            PdfDocument pdfDocument = new PdfDocument(new PdfReader(pdfPath));

            // Create a printer job
            PrinterJob printerJob = PrinterJob.GetPrinterJob();

            // Set the print parameters if required
            printerJob.PrinterName = "your printer name";

            // Create a PdfPrintable using the PdfDocument
            PdfPrintable pdfPrintable = new PdfPrintable(pdfDocument, PdfPrintable.PrintingStrategy.ShrinkToFit);

            // Set the printable to the printer job
            printerJob.SetPrintable(pdfPrintable);

            // Print the document
            printerJob.Print();

            // Close the PdfDocument
            pdfDocument.Close();
        }
    }
}

@naedisgood
Copy link

So this won't work today?

I used pdfsharp and pdfiumViewer, but I want this code to work :)) I DONT KNOW how to do so. ahaha

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment