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
}
}
@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