Agreed, printing is a thing from the past and we should think about the environment and save as much 🌳🌳🌳 as possible. However, if you’re like me, developing software for production environments, sooner or later you’ll have to get something out on paper. Preferably fully automated.
So how do we actually silent print PDF files from a Windows service? Seems like there are some ways to make this happen.
Solutions found in the wild
- Adobe Acrobat Reader
- Foxit PhantomPDF
The solutions mentioned above all depend on calling an executable providing little or no feedback from the print process. Some tools, like 2printer, check their license by making a web request each time the executable starts. While there’s nothing wrong with checking license validity, phoning home from a production server doesn’t make the IT department very happy.
Adobe Acrobat Reader seems harder to start from a Windows service as it tries to open the complete GUI. Also we must make sure that no instance is running, otherwise it simply doesn’t work. So we need to list and kill processes programmatically which can get dirty and error-prone.
Foxit PhantomPDF had an issue in several versions that it didn’t close its window after silent printing. This seems to be fixed since version 9.4, however, it still might show a window during the ‘silent’ printing process which might not be desired.
So, that’s it? Or not?
The afore mentioned solutions didn’t really fit my needs, so I decided to do my own research and start building something for free, something that just works.
This resulted in an open-source project called Print-It, which can be found on GitHub. The project contains a Windows service, hosting an ASP.NET Core API that lets you:
- list local and installed network printers
- install network printers
- print complete PDF files
- print certain PDF pages or page-ranges
How to use Print-It
Download the latest release named printit-release.zip from here. Extract the archive to f.e. C:\print-it
Currently, Print-It depends on .NET Core 3.1, however, you do not need to install the .NET Core runtime, as all required files are shipped within the archive.
To install the service, run this command from a cmd window:
sc create PrintIt binPath=C:\print-it\PrintIt.ServiceHost.exe start=auto
To start the service, run this command:
sc start PrintIt
By default, the service listens on http://localhost:7000 but this can be changed by modifying appsettings.json. Whenever changing the URL, remember to stop and restart the service.
Once the service is running, a list of printers can be retrieved by firing an HTTP GET request to http://localhost:7000/api/printers/list
New network printers can be installed by firing an HTTP POST to http://localhost:7000/api/printers/install?printerPath=\\REMOTE_PC_NAME\PRINTER-NAME
A PDF can be printed with a HTTP POST to http://localhost:7000/api/print/from-pdf. Here’s a sample snippet for sending a PDF file to the service from another .NET application:
How does Print-It work?
Print-It is a Windows service written in .NET Core (and soon .NET 5) which uses the open-source PDF library PDFium from Google. This is the same library used by Android and Google Chrome to render PDF files.
What’s more, the Print-It service itself is open-source and open for requests or bugfixes. If you need anything, do not hesitate to open an issue here.
If you’re like me and tried all different kind of existing solutions without great success, you might want to give Print-It a try and if it serves your needs.