I am trying to send pdf files to printer
Process p = new Process( );
p.StartInfo = new ProcessStartInfo( )
{
CreateNoWindow = true,
Verb = "Print",
FileName = pdfFilePath
WindowStyle := ProcessWindowsStyle.Hidden;
UseShellExecute := true;
};
p.Start( );
but i am constantly getting "No application is associated with the specified file for this operation".
I am using Edge to open pdf files (i tried also to set IE and Chrome as default .pdf apps) and i have no pdf reader installed. My question is it possible to send pdf files to the printer directly only with the default windows tools - without installing Acrobat reader etc. ?
Check this library Spire.PDF
https://www.nuget.org/packages/Spire.PDF/
PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile("Sample.pdf");
//Set the printer
pdf.PrintSettings.PrinterName = "HP LasterJet P1007";
//Only print the second and fourth page
pdf.PrintSettings.SelectSomePages(new int[] { 2,4 });
//Print the pages from 1 to 15
pdf.PrintSettings.SelectPageRange(1,15);
pdf.Print();
Here is an alternative approach that uses GemBox.Pdf, which also doesn't require having Adobe Acrobat installed:
using (PdfDocument document = PdfDocument.Load(pdfFilePath))
document.Print();
The above will print your PDF using default printer and print options.
But if needed, you can specify the targeted printer and options like this:
using (var document = PdfDocument.Load(pdfFilePath))
{
var printer = "your printer's name";
var printOptions = new PrintOptions()
{
FromPage = 2,
ToPage = 4
};
document.Print(printer, printOptions);
}
You can find more Print example's here.
You can Ghostscript which is open source there is a NuGet to use this library in with this program
This NuGet is just a library that interfaces with the Ghostscript library, you need to have Ghostscript installed on the client or add the libraries to the project for it to work
https://www.nuget.org/packages/Ghostscript.NET
Example:
using (GhostscriptProcessor processor = new
GhostscriptProcessor())
{
List<string> arg = new List<string>() {
"-empty",
"-dPrinted",
"-dBATCH",
"-dNOPAUSE",
"-dNOSAFER",
"-dNumCopies=1",
"-sDEVICE=mswinpr2",
"-sOutputFile=%printer%" + printerName,
"-f",
inputFile};
processor.StartProcessing(arg.ToArray(), null);
}
Here's the basic premise:
My user clicks some gizmos and a PDF file is spit out to his desktop. Is there some way for me to send this file to the printer queue and have it print to the locally connected printer?
string filePath = "filepathisalreadysethere";
SendToPrinter(filePath); //Something like this?
He will do this process many times. For each student in a classroom he has to print a small report card. So I generate a PDF for each student, and I'd like to automate the printing process instead of having the user generated pdf, print, generate pdf, print, generate pdf, print.
Any suggestions on how to approach this? I'm running on Windows XP with Windows Forms .NET 4.
I've found this StackOverflow question where the accepted answer suggests:
Once you have created your files, you
can print them via a command line (you
can using the Command class found in
the System.Diagnostics namespace for
that)
How would I accomplish this?
Adding a new answer to this as the question of printing PDF's in .net has been around for a long time and most of the answers pre-date the Google Pdfium library, which now has a .net wrapper. For me I was researching this problem myself and kept coming up blank, trying to do hacky solutions like spawning Acrobat or other PDF readers, or running into commercial libraries that are expensive and have not very compatible licensing terms. But the Google Pdfium library and the PdfiumViewer .net wrapper are Open Source so are a great solution for a lot of developers, myself included. PdfiumViewer is licensed under the Apache 2.0 license.
You can get the NuGet package here:
https://www.nuget.org/packages/PdfiumViewer/
and you can find the source code here:
https://github.com/pvginkel/PdfiumViewer
Here is some simple code that will silently print any number of copies of a PDF file from it's filename. You can load PDF's from a stream also (which is how we normally do it), and you can easily figure that out looking at the code or examples. There is also a WinForm PDF file view so you can also render the PDF files into a view or do print preview on them. For us I simply needed a way to silently print the PDF file to a specific printer on demand.
public bool PrintPDF(
string printer,
string paperName,
string filename,
int copies)
{
try {
// Create the printer settings for our printer
var printerSettings = new PrinterSettings {
PrinterName = printer,
Copies = (short)copies,
};
// Create our page settings for the paper size selected
var pageSettings = new PageSettings(printerSettings) {
Margins = new Margins(0, 0, 0, 0),
};
foreach (PaperSize paperSize in printerSettings.PaperSizes) {
if (paperSize.PaperName == paperName) {
pageSettings.PaperSize = paperSize;
break;
}
}
// Now print the PDF document
using (var document = PdfDocument.Load(filename)) {
using (var printDocument = document.CreatePrintDocument()) {
printDocument.PrinterSettings = printerSettings;
printDocument.DefaultPageSettings = pageSettings;
printDocument.PrintController = new StandardPrintController();
printDocument.Print();
}
}
return true;
} catch {
return false;
}
}
You can tell Acrobat Reader to print the file using (as someone's already mentioned here) the 'print' verb. You will need to close Acrobat Reader programmatically after that, too:
private void SendToPrinter()
{
ProcessStartInfo info = new ProcessStartInfo();
info.Verb = "print";
info.FileName = #"c:\output.pdf";
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
Process p = new Process();
p.StartInfo = info;
p.Start();
p.WaitForInputIdle();
System.Threading.Thread.Sleep(3000);
if (false == p.CloseMainWindow())
p.Kill();
}
This opens Acrobat Reader and tells it to send the PDF to the default printer, and then shuts down Acrobat after three seconds.
If you are willing to ship other products with your application then you could use GhostScript (free), or a command-line PDF printer such as http://www.commandlinepdf.com/ (commercial).
Note: the sample code opens the PDF in the application current registered to print PDFs, which is the Adobe Acrobat Reader on most people's machines. However, it is possible that they use a different PDF viewer such as Foxit (http://www.foxitsoftware.com/pdf/reader/). The sample code should still work, though.
I know the tag says Windows Forms... but, if anyone is interested in a WPF application method, System.Printing works like a charm.
var file = File.ReadAllBytes(pdfFilePath);
var printQueue = LocalPrintServer.GetDefaultPrintQueue();
using (var job = printQueue.AddJob())
using (var stream = job.JobStream)
{
stream.Write(file, 0, file.Length);
}
Just remember to include System.Printing reference, if it's not already included.
Now, this method does not play well with ASP.NET or Windows Service. It should not be used with Windows Forms, as it has System.Drawing.Printing. I don't have a single issue with my PDF printing using the above code.
I should mention, however, that if your printer does not support Direct Print for PDF file format, you're out of luck with this method.
The following code snippet is an adaptation of Kendall Bennett's code for printing pdf files using the PdfiumViewer library. The main difference is that a Stream is used rather than a file.
public bool PrintPDF(
string printer,
string paperName,
int copies, Stream stream)
{
try
{
// Create the printer settings for our printer
var printerSettings = new PrinterSettings
{
PrinterName = printer,
Copies = (short)copies,
};
// Create our page settings for the paper size selected
var pageSettings = new PageSettings(printerSettings)
{
Margins = new Margins(0, 0, 0, 0),
};
foreach (PaperSize paperSize in printerSettings.PaperSizes)
{
if (paperSize.PaperName == paperName)
{
pageSettings.PaperSize = paperSize;
break;
}
}
// Now print the PDF document
using (var document = PdfiumViewer.PdfDocument.Load(stream))
{
using (var printDocument = document.CreatePrintDocument())
{
printDocument.PrinterSettings = printerSettings;
printDocument.DefaultPageSettings = pageSettings;
printDocument.PrintController = new StandardPrintController();
printDocument.Print();
}
}
return true;
}
catch (System.Exception e)
{
return false;
}
}
In my case I am generating the PDF file using a library called PdfSharp and then saving the document to a Stream like so:
PdfDocument pdf = PdfGenerator.GeneratePdf(printRequest.html, PageSize.A4);
pdf.AddPage();
MemoryStream stream = new MemoryStream();
pdf.Save(stream);
MemoryStream stream2 = new MemoryStream(stream.ToArray());
One thing that I want to point out that might be helpful to other developers is that I had to install the 32 bit version of the Pdfium native DLL in order for the printing to work even though I am running Windows 10 64 bit. I installed the following two NuGet packages using the NuGet package manager in Visual Studio:
PdfiumViewer
PdfiumViewer.Native.x86.v8-xfa
The easy way:
var pi=new ProcessStartInfo("C:\file.docx");
pi.UseShellExecute = true;
pi.Verb = "print";
var process = System.Diagnostics.Process.Start(pi);
This is a slightly modified solution. The Process will be killed when it was idle for at least 1 second. Maybe you should add a timeof of X seconds and call the function from a separate thread.
private void SendToPrinter()
{
ProcessStartInfo info = new ProcessStartInfo();
info.Verb = "print";
info.FileName = #"c:\output.pdf";
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
Process p = new Process();
p.StartInfo = info;
p.Start();
long ticks = -1;
while (ticks != p.TotalProcessorTime.Ticks)
{
ticks = p.TotalProcessorTime.Ticks;
Thread.Sleep(1000);
}
if (false == p.CloseMainWindow())
p.Kill();
}
System.Diagnostics.Process.Start can be used to print a document. Set UseShellExecute to True and set the Verb to "print".
You can try with GhostScript like in this post:
How to print PDF on default network printer using GhostScript (gswin32c.exe) shell command
I know Edwin answered it above but his only prints one document. I use this code to print all files from a given directory.
public void PrintAllFiles()
{
System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo();
info.Verb = "print";
System.Diagnostics.Process p = new System.Diagnostics.Process();
//Load Files in Selected Folder
string[] allFiles = System.IO.Directory.GetFiles(Directory);
foreach (string file in allFiles)
{
info.FileName = #file;
info.CreateNoWindow = true;
info.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
p.StartInfo = info;
p.Start();
}
//p.Kill(); Can Create A Kill Statement Here... but I found I don't need one
MessageBox.Show("Print Complete");
}
It essentually cycles through each file in the given directory variable Directory - > for me it was #"C:\Users\Owner\Documents\SalesVaultTesting\" and prints off those files to your default printer.
this is a late answer, but you could also use the File.Copy method of the System.IO namespace top send a file to the printer:
System.IO.File.Copy(filename, printerName);
This works fine
You can use the DevExpress PdfDocumentProcessor.Print(PdfPrinterSettings) Method.
public void Print(string pdfFilePath)
{
if (!File.Exists(pdfFilePath))
throw new FileNotFoundException("No such file exists!", pdfFilePath);
// Create a Pdf Document Processor instance and load a PDF into it.
PdfDocumentProcessor documentProcessor = new PdfDocumentProcessor();
documentProcessor.LoadDocument(pdfFilePath);
if (documentProcessor != null)
{
PrinterSettings settings = new PrinterSettings();
//var paperSizes = settings.PaperSizes.Cast<PaperSize>().ToList();
//PaperSize sizeCustom = paperSizes.FirstOrDefault<PaperSize>(size => size.Kind == PaperKind.Custom); // finding paper size
settings.DefaultPageSettings.PaperSize = new PaperSize("Label", 400, 600);
// Print pdf
documentProcessor.Print(settings);
}
}
public static void PrintFileToDefaultPrinter(string FilePath)
{
try
{
var file = File.ReadAllBytes(FilePath);
var printQueue = LocalPrintServer.GetDefaultPrintQueue();
using (var job = printQueue.AddJob())
using (var stream = job.JobStream)
{
stream.Write(file, 0, file.Length);
}
}
catch (Exception)
{
throw;
}
}
I meet a problem about how to using c# without using Microsoft.Office.Interop.Word to covert doc to pdf. I have tried some third party solution, like spire.Doc, but they are not free, and also I found DocX_Doc in nuget, but it seems there is no tutorial about that.Is anyone knows a free solution for this problem, or any instruction about DocX_Doc. Thanks a lot.
you can use libreOffice is free license under apache 2.0 https://www.libreoffice.org/
i already tested it and it's working perefectly just you need to download soffice.exe file to convert to pdf you also can convert docx to image and other type.
here my example code that i tested it:
static string getLibreOfficePath()
{
switch (Environment.OSVersion.Platform)
{
case PlatformID.Unix:
return "/usr/bin/soffice";
case PlatformID.Win32NT:
string binaryDirectory =
System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
return #"C:\Program Files\LibreOffice\program\soffice.exe";
default:
throw new PlatformNotSupportedException("Your OS is not supported");
}
}
static void Main(string[] args)
{
string libreOfficePath = getLibreOfficePath();
ProcessStartInfo procStartInfo = new ProcessStartInfo(libreOfficePath,
string.Format("--convert-to pdf C:\\test.docx")); //test.docx => input path
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
procStartInfo.WorkingDirectory = Environment.CurrentDirectory;
Process process = new Process() { StartInfo = procStartInfo, };
process.Start();
process.WaitForExit();
// Check for failed exit code.
if (process.ExitCode != 0)
{
throw new LibreOfficeFailedException(process.ExitCode);
}
}
i hope it's helpfull for you.
Thanks.
Update:
as mentioned above by #saleem you need to use https://www.libreoffice.org/
The following solution is obsolete as those libraries are not free anymore:
For DocX library DocX and here is a sample on how to convert from word to PDF Converting .docx into (.doc, .pdf, .html) "Free"
You can check this DLL as well enter link description here
I use SautinSoft.UseOffice to do this, it's simple and easy to use but costs about 350$. Here is the link to a full tutorial:
Convert DOC (DOCX) file to PDF file in C# - Step by Step "Not Free"
Can somebody provide me a starting point or code to access an embedded resource using C#?
I have successfully embedded a couple of batch files, scripts and CAD drawings which I would like to run the batch and copy the scripts and CAD files to a location specified in the batch file.
I'm struggling to find how to specify what the item is and set the path within the EXE. The below code is what I thought would work, but it failed and the others I found online all related to XML files.
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = AppDomain.CurrentDomain.BaseDirectory + "\\Batchfile.bat";
p.Start();
I honestly don't even know if I'm looking at the correct way to do this as this is my first time using either C# or Visual Studio.
Open Solution Explorer add files you want to embed. Right click on the files then click on Properties. In Properties window and change Build Action to Embedded Resource.
After that you should write the embedded resources to file in order to be able to run it.
using System;
using System.Reflection;
using System.IO;
using System.Diagnostics;
namespace YourProject
{
public class MyClass
{
// Other Code...
private void StartProcessWithFile()
{
var assembly = Assembly.GetExecutingAssembly();
//Getting names of all embedded resources
var allResourceNames = assembly.GetManifestResourceNames();
//Selecting first one.
var resourceName = allResourceNames[0];
var pathToFile = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory) +
resourceName;
using (var stream = assembly.GetManifestResourceStream(resourceName))
using (var fileStream = File.Create(pathToFile))
{
stream.Seek(0, SeekOrigin.Begin);
stream.CopyTo(fileStream);
}
var process = new Process();
process.StartInfo.FileName = pathToFile;
process.Start();
}
}
}
XPS Printer allows us to create xps file no matter if from an image or txt or doc file.
I would like to do the same just programmatically in c#.
How do I send a file to xps printer and let the printer convert it to .xps file?
Any ideas?
I Google this but haven't found much so far.
It is possible also to use print queue to print to the XPS document writer but it will always show the file dialog.
See below other alternatives to convert and print to XPS file.
Programmatically converting files to XPS
This is not as simple as you wish many users out there have tried and there is many different ways to accomplish it all which arent the best.
One way (easiest way) to convert documents to XPS would be to use WORD 2007+ API to do it.
See below a snipped from this MSDN forum question
To programmatically convert docx to xps using Word 2007 see
Document.ExportAsFixedFormat in the Word Object Model Reference
(http://msdn2.microsoft.com/en-us/library/Bb256835.aspx). However,
since this is a server-side scenario you should take note of KB 257757
Considerations for server-side Automation of Office (see
http://support.microsoft.com/kb/257757).
Printing Images to XPS
You can easily print an Image to XPS file using the code below.
The code below is WPF example the image you pass into the write method needs to be wrapped in a canvas see this post for an example: http://denisvuyka.wordpress.com/2007/12/03/wpf-diagramming-saving-you-canvas-to-image-xps-document-or-raw-xaml/
XpsDocument xpsd = new XpsDocument("C:\\YourXPSFileName.xps", FileAccess.ReadWrite);
System.Windows.Xps.XpsDocumentWriter xw = XpsDocument.CreateXpsDocumentWriter(xpsd);
xw.Write(YourImageYouWishToWrite);
See an extended example below:
public void Export(Uri path, Canvas surface)
{
if (path == null) return;
// Save current canvas transorm
Transform transform = surface.LayoutTransform;
// Temporarily reset the layout transform before saving
surface.LayoutTransform = null;
// Get the size of the canvas
Size size = new Size(surface.Width, surface.Height);
// Measure and arrange elements
surface.Measure(size);
surface.Arrange(new Rect(size));
// Open new package
Package package = Package.Open(path.LocalPath, FileMode.Create);
// Create new xps document based on the package opened
XpsDocument doc = new XpsDocument(package);
// Create an instance of XpsDocumentWriter for the document
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
// Write the canvas (as Visual) to the document
writer.Write(surface);
// Close document
doc.Close();
// Close package
package.Close();
// Restore previously saved layout
surface.LayoutTransform = transform;
}
There are third party tools that allow you to print PDFs and other file formats to XPS.
PDF to XPS
Printing XPS files
It is possible to print XPS Documents programmatically You will need .Net 4 at least for this solution.
The example below uses the Print dialog from WPF and some of the classes from System.Windows.Xps and System.Printing.
The code below will print the Xps file to the default printer on the system however if you want to print to a different printer or even print to a print server you need to change the PrintQueue object on the print dialog.
Which is quite simple using the System.Printing namespace.
See the example below.
Please bear in mind that because it is using the WPF dialog it needs to run on a STATThread model.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Printing;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Xps.Packaging;
namespace ConsoleApplication
{
class Program
{
[STAThread]
static void Main(string[] args)
{
PrintDialog dlg = new PrintDialog();
XpsDocument xpsDoc = new XpsDocument(#"C:\DATA\personal\go\test.xps", System.IO.FileAccess.Read);
dlg.PrintDocument(xpsDoc.GetFixedDocumentSequence().DocumentPaginator, "Document title");
}
}
}
See below some Helpful links.
Xps Document documentation
Print Dialog from WPF documentation
System.Printing namespace documentation
Hope this helps and fit your needs
class Program
{
[System.MTAThreadAttribute()] // Added for clarity, but this line is redundant because MTA is the default.
static void Main(string[] args)
{
// Create the secondary thread and pass the printing method for
// the constructor's ThreadStart delegate parameter. The BatchXPSPrinter
// class is defined below.
Thread printingThread = new Thread(BatchXPSPrinter.PrintXPS);
// Set the thread that will use PrintQueue.AddJob to single threading.
printingThread.SetApartmentState(ApartmentState.STA);
// Start the printing thread. The method passed to the Thread
// constructor will execute.
printingThread.Start();
}//end Main
}//end Program class
public class BatchXPSPrinter
{
public static void PrintXPS()
{
// Create print server and print queue.
LocalPrintServer localPrintServer = new LocalPrintServer();
PrintQueue defaultPrintQueue = LocalPrintServer.GetDefaultPrintQueue();
// Prompt user to identify the directory, and then create the directory object.
Console.Write("Enter the directory containing the XPS files: ");
String directoryPath = Console.ReadLine();
DirectoryInfo dir = new DirectoryInfo(directoryPath);
// If the user mistyped, end the thread and return to the Main thread.
if (!dir.Exists)
{
Console.WriteLine("There is no such directory.");
}
else
{
// If there are no XPS files in the directory, end the thread
// and return to the Main thread.
if (dir.GetFiles("*.xps").Length == 0)
{
Console.WriteLine("There are no XPS files in the directory.");
}
else
{
Console.WriteLine("\nJobs will now be added to the print queue.");
Console.WriteLine("If the queue is not paused and the printer is working, jobs will begin printing.");
// Batch process all XPS files in the directory.
foreach (FileInfo f in dir.GetFiles("*.xps"))
{
String nextFile = directoryPath + "\\" + f.Name;
Console.WriteLine("Adding {0} to queue.", nextFile);
try
{
// Print the Xps file while providing XPS validation and progress notifications.
PrintSystemJobInfo xpsPrintJob = defaultPrintQueue.AddJob(f.Name, nextFile, false);
}
catch (PrintJobException e)
{
Console.WriteLine("\n\t{0} could not be added to the print queue.", f.Name);
if (e.InnerException.Message == "File contains corrupted data.")
{
Console.WriteLine("\tIt is not a valid XPS file. Use the isXPS Conformance Tool to debug it.");
}
Console.WriteLine("\tContinuing with next XPS file.\n");
}
}// end for each XPS file
}//end if there are no XPS files in the directory
}//end if the directory does not exist
Console.WriteLine("Press Enter to end program.");
Console.ReadLine();
}// end PrintXPS method
}// end BatchXPSPrinter class