Printing a PDF Silently with Adobe Acrobat
Asked Answered
T

11

17

I'm having 2 issues when trying to print a pdf silently in C# using adobe acrobat. I'm printing the pdfs using Process.Start().

The first issue is that I cannot launch Adobe Acrobat without specifying the full path to the executable. I assume it doesn't add it to your path when you install it. Is there an easy way to launch the newest version of acrobat on a machine without specifying full path names? I'm worried that the client is going to do an update and break my code that launches this. I'm also concerned with them installing this on machines with different versions of windows (install paths are different in 64 bit environment vs. 32 bit).

My second problem is the fact that whenever I launch acrobat and print it still leaves the acrobat window open. I thought that the command line parameters I was using would suppress all of this but apparently not.

I'm trying to launch adobe acrobat from the command line with the following syntax:

C:\Program Files (x86)\Adobe\Reader 10.0\Reader>AcroRd32.exe /t "Label.pdf" "HP4000" "HP LaserJet 4100 Series PCL6" "out.pdf"

It prints out fine but it still leaves the acrobat window up. Is there any other solution besides going out and killing the process programmatically?

Tsana answered 1/2, 2011 at 23:3 Comment(1)
All answers talking about programs or paid libraries, you don't need all that, just check my answer, free library and all code needed for thatSolis
T
28

I ended up bailing on Adobe Acrobat here and going with FoxIt Reader (Free pdf reader) to do my pdf printing. This is the code I'm using to print via FoxIt in C#:

Process pdfProcess = new Process();
pdfProcess.StartInfo.FileName = @"C:\Program Files (x86)\Foxit Software\Foxit Reader\Foxit Reader.exe";
pdfProcess.StartInfo.Arguments = string.Format(@"-p {0}", fileNameToSave);
pdfProcess.Start();

The above code prints to the default printer but there are command line parameters you can use to specify file and printer. You can use the following syntax:

Foxit Reader.exe -t "pdf filename" "printer name"

Update:

Apparently earlier versions of acrobat do not have the problem outlined above either. If you use a much older version (4.x or something similar) it does not exhibit this problem.

Some printers do support native pdf printing as well so it's possible to send the raw pdf data to the printer and it might print it. See https://support.microsoft.com/en-us/kb/322091 for sending raw data to the printer.

Update 2

In later versions of our software we ended up using a paid product:

http://www.pdfprinting.net/

Tsana answered 2/2, 2011 at 14:43 Comment(3)
This saves my life! I've tried so many things to print PDFs silenty ... the Adobe Reader via command line, a windows service invoking the Adobe Reader, some WinAPI trickery. With any approach either the Adobe Reader window came up or it simply didnt print. Thanks a lot for this hint!Trapani
I'm pretty sure with the latest version of FoxIt this is no longer supported. I think they've integrated it into the paid version at this point.Tsana
As of version 11.1 of Foxit PDF Reader, the free version still supports printing to a specific printer with the /t switch.Evelineevelinn
F
9

Nick's answer looked good to me, so I translated it to c#. It works!

using System.Diagnostics;

namespace Whatever
{
static class pdfPrint
{
    public static void pdfTest(string pdfFileName)
    {
       string processFilename = Microsoft.Win32.Registry.LocalMachine
            .OpenSubKey("Software")
            .OpenSubKey("Microsoft")
            .OpenSubKey("Windows")
            .OpenSubKey("CurrentVersion")
            .OpenSubKey("App Paths")
            .OpenSubKey("AcroRd32.exe")
            .GetValue(String.Empty).ToString();

        ProcessStartInfo info = new ProcessStartInfo();
        info.Verb = "print";
        info.FileName = processFilename;
        info.Arguments = String.Format("/p /h {0}", pdfFileName);
        info.CreateNoWindow = true;
        info.WindowStyle = ProcessWindowStyle.Hidden; 
        //(It won't be hidden anyway... thanks Adobe!)
        info.UseShellExecute = false;

        Process p = Process.Start(info);
        p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

        int counter = 0;
        while (!p.HasExited)
        {
            System.Threading.Thread.Sleep(1000);
            counter += 1;
            if (counter == 5) break;
        }
        if (!p.HasExited)
        {
            p.CloseMainWindow();
            p.Kill();
        }
    }
}

}

Foredate answered 5/3, 2015 at 7:47 Comment(2)
You can use process.WaitForExit(timeout) rather than polling.Tamah
As you are using the print verb you can use the path to the pdf in FileName and just the printer name (surrounded by quotes) for the Arguments.Tamah
T
9

I've tried both Adobe Reader and Foxit without luck. The current versions of both are very fond of popping up windows and leaving processes running. Ended up using Sumatra PDF which is very unobtrusive. Here's the code I use. Not a trace of any windows and process exits nicely when it's done printing.

    public static void SumatraPrint(string pdfFile, string printer)
    {
        var exePath = Registry.LocalMachine.OpenSubKey(
            @"SOFTWARE\Microsoft\Windows\CurrentVersion" +
            @"\App Paths\SumatraPDF.exe").GetValue("").ToString();

        var args = $"-print-to \"{printer}\" {pdfFile}";

        var process = Process.Start(exePath, args);
        process.WaitForExit();
    }
Telephotography answered 29/1, 2016 at 9:59 Comment(4)
Using Sumatra PDF worked for me. I was having trouble with Foxit leaving processes open. Thanks!Rento
Thank you for suggesting this. It works perfectly and is even open source!Ramshackle
Using Sumatra PDF prompts user to press print button. In my case I wanted to automate it. Is there a way to achieve this? Thanks in advanceAudiogenic
It works, but print quality is not that good. compare to Adobe Reader.Lau
K
7

The following is tested in both Acrobat Reader 8.1.3 and Acrobat Pro 11.0.06, and the following functionality is confirmed:

  1. Locates the default Acrobat executable on the system
  2. Sends the file to the local printer
  3. Closes Acrobat, regardless of version

string applicationPath;

var printApplicationRegistryPaths = new[]
{
    @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Acrobat.exe",
    @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\AcroRD32.exe"
};

foreach (var printApplicationRegistryPath in printApplicationRegistryPaths)
{
    using (var regKeyAppRoot = Registry.LocalMachine.OpenSubKey(printApplicationRegistryPath))
    {
        if (regKeyAppRoot == null)
        {
            continue;
        }

        applicationPath = (string)regKeyAppRoot.GetValue(null); 

        if (!string.IsNullOrEmpty(applicationPath))
        {
            return applicationPath;
        }
    }
}

// Print to Acrobat
const string flagNoSplashScreen = "/s";
const string flagOpenMinimized = "/h";

var flagPrintFileToPrinter = string.Format("/t \"{0}\" \"{1}\"", printFileName, printerName); 

var args = string.Format("{0} {1} {2}", flagNoSplashScreen, flagOpenMinimized, flagPrintFileToPrinter);

var startInfo = new ProcessStartInfo
{
    FileName = printApplicationPath, 
    Arguments = args, 
    CreateNoWindow = true, 
    ErrorDialog = false, 
    UseShellExecute = false, 
    WindowStyle = ProcessWindowStyle.Hidden
};

var process = Process.Start(startInfo);

// Close Acrobat regardless of version
if (process != null)
{
    process.WaitForInputIdle();
    process.CloseMainWindow();
}
Knelt answered 19/8, 2014 at 17:38 Comment(2)
This will not close the adobe reader window after printing, it always leaves one behind. Not sure about Acrobat, it may work differently.Tilley
This worked well for me using Foxit Reader. Version 7 is having issues printing silently, so I used WaitForExit(5000) and process.Kill().Metacarpal
B
3

Problem 1

You may be able to work your way around the registry. In HKEY_CLASSES_ROOT\.pdf\PersistentHandler\(Default) you should find a CLSID that points to a value found in one of two places. Either the CLSID folder of the same key, or (for 64 bit systems) one step down in Wow6432Node\CLSID then in that CLSID's key.

Within that key you can look for LocalServer32 and find the default string value pointing to the current exe path.

I'm not 100% on any of this, but seems plausible (though you're going to have to verify on multiple environments to confirm that in-fact locates the process you're looking for).

(Here are the docs on registry keys involved regarding PersistentHandlers)

Problem 2

Probably using the CreateNoWindow of the Process StartInfo.

Process p = new Process();
p.StartInfo.FileName = @"C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe";
p.StartInfo.Arguments = "/t \"Label.pdf\" \"HP4000\" \"HP LaserJet 4100 Series PCL6\" \"out.pdf\"";
p.CreateNoWindow = true;
p.Start();
p.WaitForExit();

(only a guess however, but I'm sure a little testing will prove it to work/not work)

Bertiebertila answered 1/2, 2011 at 23:10 Comment(4)
But, won't the process still be running (e.g. you can see it in TaskManager) even if that does manage to keep it from being shown?Dreary
@Chad: I've never had good luck printing PDFs and have googled extensivly for solutions all-over. I wanted to automate an internal task using what you're basically trying to do, but ended up bailing due to lack of documentation, problems with closing the application, or too many variations to look for. You may just be able to get a PDF library that can "internally render" the file and send it to print directly through the application, but most of the libraries that are good for this sort of thing cost money.Bertiebertila
For problem 2 I tried this out and it doesn't work the way I want it to. It basically hangs on the WaitForExit() until I manually close the acrobat window. I tried using the WaitForInputIdle() and then doing a Kill() on the process object but it kills it before the print occurs. The CreateNoWindow seems to have no affect on whether it displays the window or not either.Tsana
@Cole W, yeah the WaitForInputIdle() trick worked for versions before X, but they "fixed" that. I think they are serious about wanting their window open and staying open until the user closes it.Redan
D
3

If you use Acrobat reader 4.0 you can do things like this: "C:\Program Files\Adobe\Acrobat 4.0\Reader\Acrord32.exe" /t /s "U:\PDF_MS\SM003067K08.pdf" Planning_H2 BUT if the PDF file has been created in a newer version of Acrobat an invisible window opens

Dellinger answered 17/11, 2011 at 11:48 Comment(0)
V
3

got another solution .. its combination of other snippets from stackOverflow. When I call CloseMainWindow, and then call Kill .. adobe closes down

    Dim info As New ProcessStartInfo()
    info.Verb = "print"
    info.FileName = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("App Paths").OpenSubKey("AcroRd32.exe").GetValue(String.Empty).ToString()
    info.Arguments = String.Format("/p /h {0}", "c:\log\test.pdf")
    info.CreateNoWindow = True
    info.WindowStyle = ProcessWindowStyle.Hidden
    info.UseShellExecute = False

    Dim p As Process = Process.Start(info)
    p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden

    Dim counter As Integer = 0
    Do Until p.HasExited
        System.Threading.Thread.Sleep(1000)
        counter += 1
        If counter = 5 Then
            Exit Do
        End If
    Loop
    If p.HasExited = False Then
        p.CloseMainWindow()
        p.Kill()
    End If
Vietnamese answered 1/12, 2013 at 4:34 Comment(0)
T
1

For Problem 2

Using /h param will open the Acrobat or Adobe Reader in minimized window.

Example: C:\Program Files (x86)\Adobe\Reader 10.0\Reader>AcroRd32.exe **/h** /t "Label.pdf" "HP4000" "HP LaserJet 4100 Series PCL6" "out.pdf"

Related Documentation: https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/Acrobat_SDK_developer_faq.pdf#page=24

Twayblade answered 17/10, 2018 at 9:39 Comment(0)
S
0

You can silent print any PDF with the free library PDFium, with no need of having Foxit or Adobe Acrobat installed on your system, on a silent way. Any other not free library mentioned in a lot of posts is pure scam. Just add the PDFium free library to your project by using NuGET and here is all the code you need in an static method:

public static void PrintFileWithPDFium(string file, string printer_name, short copy_number = 1)
{
    // Create the printer settings for our printer
    PrinterSettings printerSettings = new PrinterSettings
    {
        PrinterName = printer_name,
        Copies = copy_number,
    };
    // Now print the PDF document
    using (PdfiumViewer.PdfDocument document = PdfiumViewer.PdfDocument.Load(file))
    {
        using (PrintDocument printDocument = document.CreatePrintDocument())
        {
            printDocument.PrinterSettings = printerSettings;
            //printDocument.DefaultPageSettings = pageSettings;
            printDocument.PrintController = new StandardPrintController();
            printDocument.OriginAtMargins = false;
            printDocument.Print();
        }
    }
}

Any issues just comment this post, I'm glad to help you with this

Solis answered 13/12, 2023 at 11:7 Comment(1)
Seems it can be slow to print a pdf containing many pages with Pdfiumviewer. Per my test, it can take 35 seconds to send a pdf with 50 pages to printer queue. Have you encountered this problem?Anorthosite
I
-1

You have already tried something different than Acrobat Reader, so my advice is forget about GUI apps and use 3rd party command line tool like RawFilePrinter.exe

private static void ExecuteRawFilePrinter() {
    Process process = new Process();
    process.StartInfo.FileName = "c:\\Program Files (x86)\\RawFilePrinter\\RawFilePrinter.exe";
    process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    process.StartInfo.Arguments = string.Format("-p \"c:\\Users\\Me\\Desktop\\mypdffile.pdf\" \"Canon Printer\"");

    process.Start();
    process.WaitForExit();
    if (process.ExitCode == 0) {
            //ok
    } else {
            //error
    }
}

Latest version to download: https://bigdotsoftware.pl/rawfileprinter

Interpretation answered 15/6, 2016 at 10:46 Comment(1)
That library is not free, pure scam, checkout my answerSolis
L
-1
 cmd.exe /C start acrord32 /l /p /h  D:\test.pdf

https://texwiki.texjp.org/?Adobe%20Acrobat%20Reader

Leadership answered 12/5, 2023 at 3:57 Comment(3)
The raw command line doesn't answer the OPs question and the hyperlink is to a Japanese language site which may not be helpful to the OP who is in the USA. This answer would be improved by giving some context as the OP wants to launch the print function from C#.Pappas
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Sensualist
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From ReviewTipperary

© 2022 - 2024 — McMap. All rights reserved.