title: Setting correct printer in MS Word through automation
body: <p>I have the following automation code:</p>
  
  <pre><code>lPrintSetup := fWordObject.Application.Dialogs.Item(wdDialogFilePrintSetup);
  lPrintSetup.Printer := 'MyPrinter';
  lPrintSetup.DoNotSetAsSysDefault := True;
  lPrintSetup.Execute;
  lPrintSetup := Null;
  </code></pre>
  
  <p>The <code>Printer</code> property is giving me some problems, sometimes <code>Execute</code> crashes with an EOleException (0x800A1460 (error code 5216): There is a printer error) because of a wrong printername.</p>
  
  <p>I have printer information of all printers in a <code>_PRINTER_INFO_2</code> record which I obtained by a EnumPrinters API-call. How can I compose the right printername for Word given the information in a <code>_PRINTER_INFO_2</code> record? It has work with at least Windows 2000, Word 2000 and Citrix.</p>
  
  <p>Some background info:</p>
  
  <p>Our application first filled the Printername with a self constructed printername. This gave problems with Citrix clients, so for Citrix clients we took the <code>_PRINTER_INFO_2.pPortName</code> and deleted the Client:#: part.
  This is working for the majority of our customers, but sometimes still the printer error shows up.</p>
  
  <p>What I have tried so far (on Windows XP SP3, Word 2007):</p>
  
  <ul>
  <li>Just take the <code>_PRINTER_INFO_2.pPrinterName</code>. 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).</li>
  <li>Composing a printername like this: <code>lPrintSetup.Printer := PRINTER_INFO_2.pPrinterName + ' on ' + PRINTER_INFO_2.pPortname</code>. 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. <strong>Edit: does not work always :(</strong></li>
  </ul>
  
  <p>Another solution I found on the web:</p>
  
  <p>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.</p>