The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Print word document in .NET without using interop

Does anyone know a way to print a MS Word document from within .NET without using those pesky Office PIA's?
OneDayAllWillBeManagedCode Send private email
Thursday, December 28, 2006
Consider a windows script.

Now, to print any word document, you go:

Shell  MyWordPrint.vbs “c:\path name to docuent\documentname.doc”

Note that your shell command will have to add the “ (double quotes) to the above string for the command.

Simply paste the code below into a notepad, and then rename the file with a .vbs extension. (eg:  MyWordPrint.vbs)

You could also add a few more arguments (like what printer, and the number of copies to print).

The windows script follows:

Albert D. Kallal
Edmonton, Alberta Canada

Set ArgObj = WScript.Arguments

dim wordapp
dim wordDoc
dim strFromDoc
dim strMyCopies

strMyCopies = 1

on error resume next

strFromdoc = ArgObj(0)

set wordApp = getObject(,"Word.Application")

if err.number <> 0 then
  ' word is not running - we tried to use
  ' running instance to save load time..but
  ' now we just go ahead and load word
  Call LoadWord
end if

set wordDoc = wordapp.Documents.Open (strFromDoc)

if err.number = 0 then

  wordDoc.PrintOut True, , , , , , , strMyCopies
  worddoc.Close (false)

end if


' end main -----

sub loadword

  set wordapp = createObject("word.Application")

end sub
Albert D. Kallal Send private email
Thursday, December 28, 2006
The script is air code....and

  worddoc.Close (false)
  wordapp.Print  <--- delete this line..not needed
Albert D. Kallal Send private email
Thursday, December 28, 2006
You can probably do Process.Start and pass the "print" verb as one of the parameters (or in the process start infomration structure).

That should work, but will always print to the default printer, and won't do print-preview.  I can't remember all the details off the top of my head.  Email me if you need them and I'll look them up.

Or, sell Word components for .NET, but I've never tried them.
John Rusk Send private email
Thursday, December 28, 2006
Albert, tried that too but failed to specify the printer to print to.

John, we already use the Aspose.Words component to manipulate word documents. It also has a built-in renderer that allows one to output docs to the user's screen or to a printer. Unfortunately it messes up the output most of the time.
OneDayAllWillBeManagedCode Send private email
Friday, December 29, 2006
You could consider writing an ActiveX DLL in VB6 that does all the Interop with Word.  Then interop with the ActiveX DLL from your .NET app.

A benefit of this is that your .NET code only has one COM reference to release - which can be much easier than meticulously releasing all objects of Word's object model in order to get Word to quit.
Friday, December 29, 2006
Or just get a proper Word component
Aspose makes one for instance. Google it
Feel free to mail Send private email
Saturday, December 30, 2006
If your language is VB.NET, you could use late binding. Yes, it's slow. No, it's not slow enough to matter for an operation like triggering a print job.

Something like this, for instance:

Option Strict Off
Option Explicit On

Module LateBoundWordAutomation

  Sub PrintADocument( _
        documentFile As String, _
        printerName As String _
    Dim wApp As Object = CreateObject("Word.Application")
    Dim wDoc As Object
    wApp.ActivePrinter = printerName
    wDoc = wApp.Documents.Open(documentFile)
    wDoc = Nothing
    wApp = Nothing
  End Sub

End Module
Raj Chaudhuri Send private email
Sunday, December 31, 2006

That's a good suggestion.  Even in projects that are done in C#, its easy to add one little VB.NET project into the solution, just to do the interaction with Word.  THen, the main C# code just calls the VB.NET assembly.

John Rusk Send private email
Monday, January 01, 2007
>Albert, tried that too but failed to specify the printer to print to.

Just add that as a parameter

To quote my post:

You could also add a few more arguments (like what printer, and the number of copies to print).

So, just go:

strFromdoc = ArgObj(0)
strCopies = ArgObj(1)
strPrinter = ArgObj(2)

So, to use, you just shell out with

MyWordPrint “docname”, “copies”, “what printer”

MyWordPrint “docname”,”1”,”\\ Auto HP LaserJet 5 on JULIECOMPUER”

So, you just pass doc name, copies, and printer name…

Add the folwling line:
  wordApp.ActivePrinter = strPrinter  -- add this line!
  wordDoc.PrintOut True, , , , , , , strMyCopies
  worddoc.Close (false)

end if

However, obviously Raj code is preferred, but you stated you don’t want this code inside of your main application (and, I not sure why).

As for late binding when using word, outlook, or excel, that been standard fair for just about MOST VB developers for 10+ years now, and this certainly something I continue in .net also. The performance hit is perhaps 1000 times slower, but only for the load time, and that is only 1/1000 of a second of time you save. After the instance of the object is created (and you lost that precious 1000th of a second of time), the performance from that point on is the same as early binding, but you have NONE of the early binding reference problems.

So, you loose nothing (significant) in terms of performance, but gain huge in the area of broken references.

Albert D. Kallal
Edmonton, Alberta Canada
Albert D. Kallal Send private email
Wednesday, January 03, 2007

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
Powered by FogBugz