R – Setting correct printer in MS Word through automation

automationdelphims-wordprinting

I have the following automation code:

lPrintSetup := fWordObject.Application.Dialogs.Item(wdDialogFilePrintSetup);
lPrintSetup.Printer := 'MyPrinter';
lPrintSetup.DoNotSetAsSysDefault := True;
lPrintSetup.Execute;
lPrintSetup := Null;

The Printer property is giving me some problems, sometimes Execute crashes with an EOleException (0x800A1460 (error code 5216): There is a printer error) because of a wrong printername.

I have printer information of all printers in a _PRINTER_INFO_2 record which I obtained by a EnumPrinters API-call. How can I compose the right printername for Word given the information in a _PRINTER_INFO_2 record? It has work with at least Windows 2000, Word 2000 and Citrix.

Some background info:

Our application first filled the Printername with a self constructed printername. This gave problems with Citrix clients, so for Citrix clients we took the _PRINTER_INFO_2.pPortName and deleted the Client:#: part.
This is working for the majority of our customers, but sometimes still the printer error shows up.

What I have tried so far (on Windows XP SP3, Word 2007):

  • Just take the _PRINTER_INFO_2.pPrinterName. Problem is that when you modify printernames on purpose (renaming 'PDFCreator' to 'HP DESKJET 520 on MYPC') it crashes on the latter (while selecting this printer in Word works).
  • Composing a printername like this: lPrintSetup.Printer := PRINTER_INFO_2.pPrinterName + ' on ' + PRINTER_INFO_2.pPortname. Seems to work always! But googling around showed that ' on ' is localized, so I'm not sure if that's going to work on non-english Windows versions. Edit: does not work always 🙁

Another solution I found on the web:

When reading the printername from Word it has the form of "Printername on Ne01:", where Ne01 is ranged from Ne00: to Ne99:. The solution suggested taking the printername and just try to set it while looping from Ne00: to Ne99:. When .Execute doesn't crash, you've got the right one. I'm not very fond of this 'trail and error' method.

Best Answer

I'm not sure if you've tried this, or if its of any use, but you can get a list of all the printers on the system from the Printer.Printers object make sure you add Printers to the Uses clause of your unit.

This should then list the actual names on the system and you may be able to use this information to do what you want.

Related Topic