TL;DR You can’t print to a specific printer. You have to change the default printer to what you want to use. Then print as normal.
It may be that things have changed dramatically since we first did our work in this area, but we were unable to find any way to print to a specific printer. So what we did in place of that was change the system’s default printer to what we wanted, print all the documents that we wanted on that computer, then change it back to what it was before. (actually, we quit changing it back because nothing else was expecting any particular default printer, so it didn’t matter).
Short answer:
Microsoft.Office.Interop.Word._Application _app = [some valid COM instance];
Microsoft.Office.Interop.Word.Document doc = _app.Documents.Open(ref fileName, ...);
doc.Application.ActivePrinter = "name of printer";
doc.PrintOut(/* ref options */);
But, we found this highly unreliable! Read on for more details:
If you haven’t done so already, I heavily suggest building your own wrapper classes to deal with all the mundane work bits of _Document
and _Application
. It may not be as bad now as it was then (dynamic
was not an option for us), but it’s still a good idea. You’ll note that certain delicious bits of code are absent from this … I tried to focus on the code that is related to what you are asking. Also, this DocWrapper
class is a merging of many separate parts of the code — forgive the disorder. Lastly, if you consider the exception handling odd (or just poor design by throwing Exception) — remember I’m trying to put together parts of code from many places (while also leaving out our own custom types). Read the comments in the code, they matter.
class DocWrapper
{
private const int _exceptionLimit = 4;
// should be a singleton instance of wrapper for Word
// the code below assumes this was set beforehand
// (e.g. from another helper method)
private static Microsoft.Office.Interop.Word._Application _app;
public virtual void PrintToSpecificPrinter(string fileName, string printer)
{
// Sometimes Word fails, so needs to be restarted.
// Sometimes it's not Word's fault.
// Either way, having this in a retry-loop is more robust.
for (int retry = 0; retry < _exceptionLimit; retry++)
{
if (TryOncePrintToSpecificPrinter(fileName, printer))
break;
if (retry == _exceptionLimit - 1) // this was our last chance
{
// if it didn't have actual exceptions, but was not able to change the printer, we should notify somebody:
throw new Exception("Failed to change printer.");
}
}
}
private bool TryOncePrintToSpecificPrinter(string fileName, string printer)
{
Microsoft.Office.Interop.Word.Document doc = null;
try
{
doc = OpenDocument(fileName);
if (!SetActivePrinter(doc, printer))
return false;
Print(doc);
return true; // we did what we wanted to do here
}
catch (Exception e)
{
if (retry == _exceptionLimit)
{
throw new Exception("Word printing failed.", e);
}
// restart Word, remembering to keep an appropriate delay between Quit and Start.
// this should really be handled by wrapper classes
}
finally
{
if (doc != null)
{
// release your doc (COM) object and do whatever other cleanup you need
}
}
return false;
}
private void Print(Microsoft.Office.Interop.Word.Document doc)
{
// do the actual printing:
doc.Activate();
Thread.Sleep(TimeSpan.FromSeconds(1)); // emperical testing found this to be sufficient for our system
// (a delay may not be required for you if you are printing only one document at a time)
doc.PrintOut(/* ref objects */);
}
private bool SetActivePrinter(Microsoft.Office.Interop.Word.Document doc, string printer)
{
string oldPrinter = GetActivePrinter(doc); // save this if you want to preserve the existing "default"
if (printer == null)
return false;
if (oldPrinter != printer)
{
// conditionally change the default printer ...
// we found it inefficient to change the default printer if we don't have to. YMMV.
doc.Application.ActivePrinter = printer;
Thread.Sleep(TimeSpan.FromSeconds(5)); // emperical testing found this to be sufficient for our system
if (GetActivePrinter(doc) != printer)
{
// don't quit-and-restart Word, this one actually isn't Word's fault -- just try again
return false;
}
// successful printer switch! (as near as anyone can tell)
}
return true;
}
private Microsoft.Office.Interop.Word.Document OpenDocument(string fileName)
{
return _app.Documents.Open(ref fileName, /* other refs */);
}
private string GetActivePrinter(Microsoft.Office.Interop.Word._Document doc)
{
string activePrinter = doc.Application.ActivePrinter;
int onIndex = activePrinter.LastIndexOf(" on ");
if (onIndex >= 0)
{
activePrinter = activePrinter.Substring(0, onIndex);
}
return activePrinter;
}
}
title | description | ms.date | ms.topic | dev_langs | helpviewer_keywords | author | ms.author | manager | ms.technology | ms.workload | ||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
How to: Programmatically print documents |
Learn how you can print an entire Microsoft Word document, or part of a document, to your default printer. |
02/02/2017 |
how-to |
|
|
John-Hart |
johnhart |
jmartens |
office-development |
office |
How to: Programmatically print documents
[!INCLUDE Visual Studio]
You can print an entire Microsoft Office Word document, or part of a document, to your default printer.
[!INCLUDEappliesto_wdalldocapp]
Print a document that is part of a document-level customization
To print the entire document
-
Call the xref:Microsoft.Office.Tools.Word.Document.PrintOut%2A method of the
ThisDocument
class in your project to print the entire document. To use this example, run the code from theThisDocument
class.C#
:::code language=»csharp» source=»../vsto/codesnippet/CSharp/Trin_VstcoreWordAutomationCS/ThisDocument.cs» id=»Snippet11″:::
VB
:::code language=»vb» source=»../vsto/codesnippet/VisualBasic/Trin_VstcoreWordAutomationVB/ThisDocument.vb» id=»Snippet11″:::
To print the current page of the document
-
Call the xref:Microsoft.Office.Tools.Word.Document.PrintOut%2A method of the
ThisDocument
class in your project and specify that one copy of the current page be printed. To use this example, run the code from theThisDocument
class.C#
:::code language=»csharp» source=»../vsto/codesnippet/CSharp/Trin_VstcoreWordAutomationCS/ThisDocument.cs» id=»Snippet12″:::
VB
:::code language=»vb» source=»../vsto/codesnippet/VisualBasic/Trin_VstcoreWordAutomationVB/ThisDocument.vb» id=»Snippet12″:::
Print a document by using a VSTO Add-in
To print an entire document
-
Call the xref:Microsoft.Office.Interop.Word._Document.PrintOut%2A method of the xref:Microsoft.Office.Interop.Word.Document object that you want to print. The following code example prints the active document. To use this example, run the code from the
ThisAddIn
class in your project.C#
:::code language=»csharp» source=»../vsto/codesnippet/CSharp/Trin_VstcoreWordAutomationAddIn/ThisAddIn.cs» id=»Snippet11″:::
VB
:::code language=»vb» source=»../vsto/codesnippet/VisualBasic/Trin_VstcoreWordAutomationAddIn/ThisAddIn.vb» id=»Snippet11″:::
To print the current page of a document
-
Call the xref:Microsoft.Office.Interop.Word._Document.PrintOut%2A method of the xref:Microsoft.Office.Interop.Word.Document object that you want to print, and specify that one copy of the current page be printed. The following code example prints the active document. To use this example, run the code from the
ThisAddIn
class in your project.C#
:::code language=»csharp» source=»../vsto/codesnippet/CSharp/Trin_VstcoreWordAutomationAddIn/ThisAddIn.cs» id=»Snippet12″:::
VB
:::code language=»vb» source=»../vsto/codesnippet/VisualBasic/Trin_VstcoreWordAutomationAddIn/ThisAddIn.vb» id=»Snippet12″:::
See also
- Optional parameters in Office solutions
- Remove From My Forums
-
Question
-
How to print a word document?
Many thanks for replying.
Answers
-
The Print method of the Document object, when automating the Word application.
-
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
//vincent
using System.Diagnostics;namespace WindowsApplication16
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.timer1.Start();
print();
}
private void print()
{
try
{
// Declaring the object variables we will need later
object varFileName = «c:\temp\test.docx»;
object varFalseValue = false;
object varTrueValue = true;
object varMissing = Type.Missing;
// Create a reference to MS Word application
Microsoft.Office.Interop.Word.Application varWord = new Microsoft.Office.Interop.Word.Application();
// Creates a reference to a word document
Microsoft.Office.Interop.Word.Document varDoc = varWord.Documents.Open(ref varFileName, ref varMissing, ref varFalseValue, ref varMissing, ref varMissing, ref varMissing, ref varMissing, ref varMissing, ref varMissing, ref varMissing, ref varMissing, ref varMissing, ref varMissing, ref varMissing, ref varMissing, ref varMissing);
// Activate the document
varDoc.Activate();// Print the document
object Background = true;
object PrintToFile = true;
object OutputFileName = «c:\temp\test.tif»;//varDoc.PrintOut(ref varTrueValue, ref varFalseValue, ref varMissing, ref varMissing, ref varMissing, ref varMissing,ref varMissing, ref varMissing, ref varMissing, ref varMissing, ref varFalseValue, ref varMissing, ref varMissing,ref varMissing, ref varMissing, ref varMissing, ref varMissing, ref varMissing);
varDoc.PrintOut(ref Background, ref varFalseValue, ref varMissing, ref OutputFileName, ref varMissing, ref varMissing, ref varMissing, ref varMissing, ref varMissing, ref varMissing, ref PrintToFile, ref varMissing, ref varMissing, ref varMissing, ref varMissing, ref varMissing, ref varMissing, ref varMissing);varDoc.Close(ref varMissing, ref varMissing, ref varMissing);
varWord.Quit(ref varMissing, ref varMissing, ref varMissing);
// Send mail with this document as an attachment
//varDoc.SendMail();
}
catch (Exception varE)
{
MessageBox.Show(«Error:n» + varE.Message, «Error message»);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
// Get all instances of Notepad running on the local
Process[] localByName = Process.GetProcessesByName(«rundll32»);
foreach (Process tempProcess in localByName)
{
tempProcess.Kill();
}
}
}
}
Introduction
I feel I need to share this pain. I have been struggling for days now to get something simple to work for me. That is to print out a Word document (RTF format) to a printer using Word. It also has to work with multiple versions of Word (so far 2000 and 2003). I thought I would share everything that I have learnt.
If you want this to work for multiple versions, install the earliest version of Word and Add Reference to its COM component and develop against these.
Next to the code…
The Code
Word.ApplicationClass ac = new Word.ApplicationClass(); Word.Application app = ac.Application; app.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone; object filename = "myFile.rtf"; object missingValue = Type.Type.Missing; Word.Document document = app.Documents.OpenOld(ref filename, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue); app.ActivePrinter = "My Printer Name"; object myTrue = true; object myFalse = false; m_App.ActiveDocument.PrintOutOld(ref myTrue, ref myFalse, ref missingValue, ref missingValue, ref missingValue, missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref myFalse, ref missingValue, ref missingValue, ref m_MissingValue); document.Close(ref missingValue, ref missingValue, ref missingValue); while(m_App.BackgroundPrintingStatus > 0) { System.Threading.Thread.Sleep(250); } app.Quitref missingValue, ref missingValue, ref missingValue);
I do not claim that this is perfect, but it’s as good as I can get. It works on my machine anyway.
History
- 15th July, 2005: Initial post
This member has not yet provided a Biography. Assume it’s interesting and varied, and probably something to do with programming.
Skip to content
We can use can use the PrintOut method to print a Microsoft Office Word document, following example code shows how to print whole word document in vb.net and c# languages:
Code Sample :
[vb.net]
Private Sub PrintWordDocument() Dim objWord As Word.Application Dim objDoc As Word.Document objWord = CreateObject("Word.Application") objDoc = objWord.Documents.Open("D:Test.docx") objDoc.PrintOut() objDoc.Close() objDoc = Nothing objWord.Quit() End Sub
[c#]
private void PrintWordDocument() { object objMissing = System.Reflection.Missing.Value; Microsoft.Office.Interop.Word.Application objWord; Microsoft.Office.Interop.Word.Document objDoc; objWord = new Microsoft.Office.Interop.Word.Application(); object fileName = @"D:Test.docx"; objDoc=objWord.Documents.Open(ref fileName, ref objMissing, ref objMissing, ref objMissing, ref objMissing, ref objMissing, ref objMissing, ref objMissing, ref objMissing, ref objMissing, ref objMissing, ref objMissing, ref objMissing, ref objMissing, ref objMissing, ref objMissing); object copies = "1"; object pages = ""; object range = Microsoft.Office.Interop.Word.WdPrintOutRange.wdPrintAllDocument; object items = Microsoft.Office.Interop.Word.WdPrintOutItem.wdPrintDocumentContent; object pageType = Microsoft.Office.Interop.Word.WdPrintOutPages.wdPrintAllPages; object objTrue = true; object objFalse = false; objDoc.PrintOut( ref objTrue, ref objFalse, ref range, ref objMissing, ref objMissing, ref objMissing, ref items, ref copies, ref pages, ref pageType, ref objFalse, ref objTrue, ref objMissing, ref objFalse, ref objMissing, ref objMissing, ref objMissing, ref objMissing); }
The following code is from an example that shows a couple of different methods to print a Microsoft Word document to a PDF file.
At the bottom of this page you will find a zip file with the entire solution for Microsoft Visual Studio 2010.
One of the printing methods used are using printing via Verbs. This is documented in detail here http://msdn.microsoft.com/en-us/library/bb776883.aspx?ppud=4
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Bullzip.PdfWriter;
namespace PrintWordDocument
{
public partial class Form1 : Form
{
const string
PRINTERNAME = «Bullzip PDF Printer»;
public Form1()
{
InitializeComponent();
}
/// <summary>
/// This function shows how
to print a Microsoft Word document
/// using the default
printing application for the document type.
/// </summary>
private static void PrintUsingVerb()
{
try
{
string fileName = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
+ @»….test.doc»;
//
// Set the PDF settings
//
DateTime now = DateTime.Now;
PdfSettings pdfSettings = new PdfSettings();
pdfSettings.PrinterName = PRINTERNAME;
pdfSettings.SetValue(«Output»,
string.Format(@»<desktop>test
{0,0:00}-{1,0:00}-{2,0:00}.pdf», now.Hour, now.Minute,
now.Second));
pdfSettings.SetValue(«ShowPDF»,
«yes»);
pdfSettings.SetValue(«ShowSettings»,
«never»);
pdfSettings.SetValue(«ShowSaveAS»,
«never»);
pdfSettings.SetValue(«ShowProgress»,
«no»);
pdfSettings.SetValue(«ShowProgressFinished»,
«no»);
pdfSettings.SetValue(«ConfirmOverwrite»,
«yes»);
pdfSettings.WriteSettings(PdfSettingsFileType.RunOnce);
PdfUtil.PrintFile(fileName, PRINTERNAME);
}
catch (Exception
ex)
{
MessageBox.Show(«Error printing Word document.nn» +
ex.Message);
}
}
/// <summary>
/// This function shows how
to print a document to PDF
/// using the Microsoft
Word interop.
/// </summary>
private static void PrintDocumentUsingInterop()
{
Microsoft.Office.Interop.Word.Application
word = null;
Microsoft.Office.Interop.Word.Document
doc = null;
try
{
word = new
Microsoft.Office.Interop.Word.Application();
object fileName = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
+ @»….test.doc»;
word.Visible = false;
doc = word.Documents.Open(ref fileName);
word.ActivePrinter = PRINTERNAME;
//
// Set
the PDF settings
//
DateTime now = DateTime.Now;
PdfSettings pdfSettings = new PdfSettings();
pdfSettings.PrinterName = PRINTERNAME;
pdfSettings.SetValue(«Output»,
string.Format(@»<desktop>test
{0,0:00}-{1,0:00}-{2,0:00}.pdf», now.Hour, now.Minute,
now.Second));
pdfSettings.SetValue(«ShowPDF»,
«yes»);
pdfSettings.SetValue(«ShowSettings»,
«never»);
pdfSettings.SetValue(«ShowSaveAS»,
«never»);
pdfSettings.SetValue(«ShowProgress»,
«no»);
pdfSettings.SetValue(«ShowProgressFinished»,
«no»);
pdfSettings.SetValue(«ConfirmOverwrite»,
«yes»);
pdfSettings.WriteSettings(PdfSettingsFileType.RunOnce);
doc.PrintOut();
word.Quit();
}
catch (Exception
ex)
{
MessageBox.Show(«Error printing Word document.nn» +
ex.Message);
}
}
private void
button1_Click(object sender, EventArgs e)
{
PrintDocumentUsingInterop();
}
private void
button2_Click(object sender, EventArgs e)
{
PrintUsingVerb();
}
}
}
This seems like such a simple need, but for some reason I cannot find how I can accomplish this. I have code like this:
Microsoft.Office.Interop.Word.Application word = new Microsoft.Office.Interop.Word.Application();
MemoryStream documentStream = getDocStream();
FileInfo wordFile = new FileInfo("c:\test.docx");
object fileObject = wordFile.FullName;
object oMissing = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Word.Document doc = wordInstance.Documents.Open(ref fileObject, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);
doc.Activate();
doc.PrintOut(oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing);
I need to have a config setting drive which printer and tray are used. After searching around I found Microsoft.Office.Interop.Word.Application.ActivePrinter which is a settable string property that the documentation says takes «the name of the active printer», but I don’t know what it means for a printer to the the «Active Printer», especially when I have two of them. How can this be accomplished?
TL;DR You can’t print to a specific printer. You have to change the default printer to what you want to use. Then print as normal.
It may be that things have changed dramatically since we first did our work in this area, but we were unable to find any way to print to a specific printer. So what we did in place of that was change the system’s default printer to what we wanted, print all the documents that we wanted on that computer, then change it back to what it was before. (actually, we quit changing it back because nothing else was expecting any particular default printer, so it didn’t matter).
Short answer:
Microsoft.Office.Interop.Word._Application _app = [some valid COM instance];
Microsoft.Office.Interop.Word.Document doc = _app.Documents.Open(ref fileName, ...);
doc.Application.ActivePrinter = "name of printer";
doc.PrintOut(/* ref options */);
But, we found this highly unreliable! Read on for more details:
If you haven’t done so already, I heavily suggest building your own wrapper classes to deal with all the mundane work bits of _Document
and _Application
. It may not be as bad now as it was then (dynamic
was not an option for us), but it’s still a good idea. You’ll note that certain delicious bits of code are absent from this … I tried to focus on the code that is related to what you are asking. Also, this DocWrapper
class is a merging of many separate parts of the code — forgive the disorder. Lastly, if you consider the exception handling odd (or just poor design by throwing Exception) — remember I’m trying to put together parts of code from many places (while also leaving out our own custom types). Read the comments in the code, they matter.
class DocWrapper
{
private const int _exceptionLimit = 4;
// should be a singleton instance of wrapper for Word
// the code below assumes this was set beforehand
// (e.g. from another helper method)
private static Microsoft.Office.Interop.Word._Application _app;
public virtual void PrintToSpecificPrinter(string fileName, string printer)
{
// Sometimes Word fails, so needs to be restarted.
// Sometimes it's not Word's fault.
// Either way, having this in a retry-loop is more robust.
for (int retry = 0; retry < _exceptionLimit; retry++)
{
if (TryOncePrintToSpecificPrinter(fileName, printer))
break;
if (retry == _exceptionLimit - 1) // this was our last chance
{
// if it didn't have actual exceptions, but was not able to change the printer, we should notify somebody:
throw new Exception("Failed to change printer.");
}
}
}
private bool TryOncePrintToSpecificPrinter(string fileName, string printer)
{
Microsoft.Office.Interop.Word.Document doc = null;
try
{
doc = OpenDocument(fileName);
if (!SetActivePrinter(doc, printer))
return false;
Print(doc);
return true; // we did what we wanted to do here
}
catch (Exception e)
{
if (retry == _exceptionLimit)
{
throw new Exception("Word printing failed.", e);
}
// restart Word, remembering to keep an appropriate delay between Quit and Start.
// this should really be handled by wrapper classes
}
finally
{
if (doc != null)
{
// release your doc (COM) object and do whatever other cleanup you need
}
}
return false;
}
private void Print(Microsoft.Office.Interop.Word.Document doc)
{
// do the actual printing:
doc.Activate();
Thread.Sleep(TimeSpan.FromSeconds(1)); // emperical testing found this to be sufficient for our system
// (a delay may not be required for you if you are printing only one document at a time)
doc.PrintOut(/* ref objects */);
}
private bool SetActivePrinter(Microsoft.Office.Interop.Word.Document doc, string printer)
{
string oldPrinter = GetActivePrinter(doc); // save this if you want to preserve the existing "default"
if (printer == null)
return false;
if (oldPrinter != printer)
{
// conditionally change the default printer ...
// we found it inefficient to change the default printer if we don't have to. YMMV.
doc.Application.ActivePrinter = printer;
Thread.Sleep(TimeSpan.FromSeconds(5)); // emperical testing found this to be sufficient for our system
if (GetActivePrinter(doc) != printer)
{
// don't quit-and-restart Word, this one actually isn't Word's fault -- just try again
return false;
}
// successful printer switch! (as near as anyone can tell)
}
return true;
}
private Microsoft.Office.Interop.Word.Document OpenDocument(string fileName)
{
return _app.Documents.Open(ref fileName, /* other refs */);
}
private string GetActivePrinter(Microsoft.Office.Interop.Word._Document doc)
{
string activePrinter = doc.Application.ActivePrinter;
int onIndex = activePrinter.LastIndexOf(" on ");
if (onIndex >= 0)
{
activePrinter = activePrinter.Substring(0, onIndex);
}
return activePrinter;
}
}