2012-06-27 107 views
3

我們有一個管理打印文檔的項目。起初我想知道爲什麼打印選項不能在一個地方設置。例如打印機托盤選擇爲第一頁,並且爲其它頁面可以使用的MS Word自動化來完成:使用高級選項打印(紙盒選擇,雙面打印,訂書釘)

var doc = _applicationObject.Documents.OpenNoRepairDialog(FileName: ref sourceFile, ReadOnly: ref readOnly, 
                   AddToRecentFiles: ref addToRecentFiles, 
                   Visible: ref visible); 
doc.PageSetup.FirstPageTray = (WdPaperTray) firstPageTrayCode; 
doc.PageSetup.OtherPagesTray = (WdPaperTray) otherPagesTrayCode; 
_applicationObject.ActivePrinter = printerPath; 
doc.Activate(); 
_applicationObject.PrintOut(Background: ref backgroundPrint, FileName: sourceFile); 
doc.Close(ref saveChanges, ref _missing, ref _missing); 

在打印機托盤上面的代碼被指定爲整數,因爲有些打印機有托盤不非標準值(我們在惠普有這個問題 - 它的托盤代碼爲here)。因此,我們首先檢索什麼托盤打印機擁有,使用代碼:

var setting = new PrinterSettings(); 
setting.PrinterName = myPrinterName; 
foreach (PaperSource tray in setting.PaperSources) 
{ 
    Console.WriteLine("\t{0}: #{1}", tray.SourceName, tray.RawKind); 
} 

而且此代碼的​​工作,沒有任何問題。

但是在這裏沒有辦法指定雙面和訂書釘選項。 Duplex可以使用驅動程序功能OpenPrinter和SetPrinter,如描述的here以及微軟推薦的this forum thread主打完全是不清楚如果有人知道如何實現這一點,請讓我知道。使用Stapling枚舉類似於this MSDN article是無用的,因爲它需要自定義渲染文檔才能打印。

我描述了情況以及部件是如何實現的。 適用於我們的環境:Windows Server 2008 R2,MS Office 2010 x32,打印機HP LaserJet P2055和理光Nashuatec DSm635。使用本機和通用PCL6/PCL5e驅動程序進行測試:雙面打印和紙盒選擇按預期工作。

但是部署應用程序客戶端後,打印機(的HP LaserJet 4250和理光Aficio MP C7501)從默認盤和不帶雙面打印做印刷始終。嘗試了幾個不同的驅動程序,結果完全一樣。

在這兩種環境下,打印機都是網絡打印機。因此,爲了使它們應用雙面打印設置,使用打印機驅動程序,我們需要在服務器上安裝本地驅動程序並製作本地打印機,建議我的微軟上this support forum thread

雖然使用的環境和打印機看起來非常相似,但其他打印機不工作。任何幫助將不勝感激。

+1

看一看理光Print&Share軟件。在那裏你可以配置非常複雜的設置,可能是你想要使用的東西。 – juFo

+0

我有一個類似的問題,這是我的答案:http://stackoverflow.com/a/33239717/2559297 –

回答

5

如果有人需要它,我想出了一個解決方法,基於將打印機設置內存塊存儲在二進制文件中,然後恢復它。這個想法在this blog post中有描述,但是在複製粘貼時它不起作用(它僅適用於某些驅動程序和某些設置,而其他打印選項被忽略)。

所以我重拍了一下,現在它可以支持我在任何打印機(兼容驅動程序)上測試過的所有設置。當然,如果您使用其他打印機的驅動程序,例如它不起作用。

thi方法的缺點當然是您應該首先將默認打印機首選項(在控制面板中)設置爲您所需的。這當然不總是可能的,但至少在某些情況下它可以提供幫助。

所以測試util的是能夠對打印機設置保存到一個文件的完整的源代碼,重新載入該文件到打印機,並使用指定的設置文件打印文檔:

using System; 
using System.Collections.Generic; 
using System.Drawing.Printing; 
using System.IO; 
using System.Linq; 
using System.Runtime.InteropServices; 
using System.Text; 
using Microsoft.Office.Interop.Word; 

namespace PrintAdvancedTest 
{ 
    [StructLayout(LayoutKind.Sequential)] 
    public struct PRINTER_DEFAULTS 
    { 
     public int pDatatype; 
     public int pDevMode; 
     public int DesiredAccess; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct PRINTER_INFO_2 
    { 
     [MarshalAs(UnmanagedType.LPStr)] 
     public readonly string pServerName; 
     [MarshalAs(UnmanagedType.LPStr)] 
     public readonly string pPrinterName; 
     [MarshalAs(UnmanagedType.LPStr)] 
     public readonly string pShareName; 
     [MarshalAs(UnmanagedType.LPStr)] 
     public readonly string pPortName; 
     [MarshalAs(UnmanagedType.LPStr)] 
     public readonly string pDriverName; 
     [MarshalAs(UnmanagedType.LPStr)] 
     public readonly string pComment; 
     [MarshalAs(UnmanagedType.LPStr)] 
     public readonly string pLocation; 
     public IntPtr pDevMode; 
     [MarshalAs(UnmanagedType.LPStr)] 
     public readonly string pSepFile; 
     [MarshalAs(UnmanagedType.LPStr)] 
     public readonly string pPrintProcessor; 
     [MarshalAs(UnmanagedType.LPStr)] 
     public readonly string pDatatype; 
     [MarshalAs(UnmanagedType.LPStr)] 
     public readonly string pParameters; 
     public IntPtr pSecurityDescriptor; 
     public readonly Int32 Attributes; 
     public readonly Int32 Priority; 
     public readonly Int32 DefaultPriority; 
     public readonly Int32 StartTime; 
     public readonly Int32 UntilTime; 
     public readonly Int32 Status; 
     public readonly Int32 cJobs; 
     public readonly Int32 AveragePPM; 
    } 

    public class PrintSettings 
    { 
     private const short CCDEVICENAME = 32; 
     private const short CCFORMNAME = 32; 

     //Constants for DEVMODE 
     // Constants for DocumentProperties 
     private const int DM_MODIFY = 8; 
     private const int DM_COPY = 2; 
     private const int DM_IN_BUFFER = DM_MODIFY; 
     private const int DM_OUT_BUFFER = DM_COPY; 
     // const intants for dmOrientation 
     private const int DMORIENT_PORTRAIT = 1; 
     private const int DMORIENT_LANDSCAPE = 2; 
     // const intants for dmPrintQuality 
     private const int DMRES_DRAFT = (-1); 
     private const int DMRES_HIGH = (-4); 
     private const int DMRES_LOW = (-2); 
     private const int DMRES_MEDIUM = (-3); 
     // const intants for dmTTOption 
     private const int DMTT_BITMAP = 1; 
     private const int DMTT_DOWNLOAD = 2; 
     private const int DMTT_DOWNLOAD_OUTLINE = 4; 
     private const int DMTT_SUBDEV = 3; 
     // const intants for dmColor 
     private const int DMCOLOR_COLOR = 2; 
     private const int DMCOLOR_MONOCHROME = 1; 
     // const intants for dmCollate 
     private const int DMCOLLATE_FALSE = 0; 
     private const int DMCOLLATE_TRUE = 1; 
     // const intants for dmDuplex 
     private const int DMDUP_HORIZONTAL = 3; 
     private const int DMDUP_SIMPLEX = 1; 
     private const int DMDUP_VERTICAL = 2; 

     //const for security access 
     private const int PRINTER_ACCESS_ADMINISTER = 0x4; 
     private const int PRINTER_ACCESS_USE = 0x8; 
     private const int STANDARD_RIGHTS_REQUIRED = 0xF0000; 

     private const int PRINTER_ALL_ACCESS = 
      (STANDARD_RIGHTS_REQUIRED | PRINTER_ACCESS_ADMINISTER 
      | PRINTER_ACCESS_USE); 


     /* field selection bits */ 
     private const int DM_ORIENTATION = 0x00000001; 
     private const int DM_PAPERSIZE = 0x00000002; 
     private const int DM_PAPERLENGTH = 0x00000004; 
     private const int DM_PAPERWIDTH = 0x00000008; 
     private const int DM_SCALE = 0x00000010; 
     private const int DM_POSITION = 0x00000020; 
     private const int DM_NUP = 0x00000040; 
     private const int DM_DISPLAYORIENTATION = 0x00000080; 
     private const int DM_COPIES = 0x00000100; 
     private const int DM_DEFAULTSOURCE = 0x00000200; 
     private const int DM_PRINTQUALITY = 0x00000400; 
     private const int DM_COLOR = 0x00000800; 
     private const int DM_DUPLEX = 0x00001000; 
     private const int DM_YRESOLUTION = 0x00002000; 
     private const int DM_TTOPTION = 0x00004000; 
     private const int DM_COLLATE = 0x00008000; 
     private const int DM_FORMNAME = 0x00010000; 
     private const int DM_LOGPIXELS = 0x00020000; 
     private const int DM_BITSPERPEL = 0x00040000; 
     private const int DM_PELSWIDTH = 0x00080000; 
     private const int DM_PELSHEIGHT = 0x00100000; 
     private const int DM_DISPLAYFLAGS = 0x00200000; 
     private const int DM_DISPLAYFREQUENCY = 0x00400000; 
     private const int DM_ICMMETHOD = 0x00800000; 
     private const int DM_ICMINTENT = 0x01000000; 
     private const int DM_MEDIATYPE = 0x02000000; 
     private const int DM_DITHERTYPE = 0x04000000; 
     private const int DM_PANNINGWIDTH = 0x08000000; 
     private const int DM_PANNINGHEIGHT = 0x10000000; 
     private const int DM_DISPLAYFIXEDOUTPUT = 0x20000000; 


     [StructLayout(LayoutKind.Sequential)] 
     public struct DEVMODE 
     { 
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCDEVICENAME)] 
      public string dmDeviceName; 
      public short dmSpecVersion; 
      public short dmDriverVersion; 
      public short dmSize; 
      public short dmDriverExtra; 
      public int dmFields; 
      public short dmOrientation; 
      public short dmPaperSize; 
      public short dmPaperLength; 
      public short dmPaperWidth; 
      public short dmScale; 
      public short dmCopies; 
      public short dmDefaultSource; 
      public short dmPrintQuality; 
      public short dmColor; 
      public short dmDuplex; 
      public short dmYResolution; 
      public short dmTTOption; 
      public short dmCollate; 
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCFORMNAME)] 
      public string dmFormName; 
      public short dmUnusedPadding; 
      public short dmBitsPerPel; 
      public int dmPelsWidth; 
      public int dmPelsHeight; 
      public int dmDisplayFlags; 
      public int dmDisplayFrequency; 
     } 

     static void Main(string[] args) 
     { 
      Dictionary<string, Action> commands = new Dictionary<string, Action> 
                 { 
                  {"save", PrinterPreferencesSave}, 
                  {"print", PrinterPreferencesPrint}, 
                  {"set", PrinterPreferencesSet}, 
                  {"info", PrinterInfo} 
                 }; 

      while (true) 
      { 
       Console.Write("Command ({0}): ", string.Join(", ", commands.Keys)); 
       string command = Console.ReadLine(); 
       Action action; 
       if (!commands.TryGetValue(command, out action)) 
       { 
        Console.WriteLine("Invalid command"); 
       } 
       else 
       { 
        action(); 
       } 
      } 
     } 

     static void PrinterPreferencesSave() 
     { 
      Console.Write("Printer name: "); 
      string printerName = Console.ReadLine(); 
      Console.Write("Settings file path format: "); 
      string SettingsFileNameFormat = Console.ReadLine(); 
      string testName; 

      while (true) 
      { 
       Console.Write("SAVE: Settings set name: "); 
       testName = Console.ReadLine(); 
       if (testName == "end") 
       { 
        break; 
       } 
       getDevMode(printerName, string.Format(SettingsFileNameFormat, testName)); 
      } 
     } 

     static void PrinterPreferencesPrint() 
     { 
      Console.Write("Printer name: "); 
      string printerName = Console.ReadLine(); 
      Console.Write("Settings file path format: "); 
      string SettingsFileNameFormat = Console.ReadLine(); 
      Console.Write("Document to print: "); 
      string docToPrintPath = Console.ReadLine(); 

      string testName; 
      while (true) 
      { 
       Console.Write("PRINT: Settings set name: "); 
       testName = Console.ReadLine(); 
       if (testName == "end") 
       { 
        break; 
       } 
       string filePath = string.Format(SettingsFileNameFormat, testName); 
       if (!File.Exists(filePath)) 
       { 
        Console.WriteLine("File {0} not exists", filePath); 
        return; 
       } 
       var success = setDevMode(printerName, filePath); 
       if (success) 
       { 
        PrintWordDocument(docToPrintPath, printerName); 
       } 
      } 
     } 

     static void PrinterPreferencesSet() 
     { 
      Console.Write("Printer name: "); 
      string printerName = Console.ReadLine(); 
      Console.Write("Settings file path format: "); 
      string SettingsFileNameFormat = Console.ReadLine(); 

      string testName; 
      while (true) 
      { 
       Console.Write("SET: Settings set name: "); 
       testName = Console.ReadLine(); 
       if (testName == "end") 
       { 
        break; 
       } 
       string filePath = string.Format(SettingsFileNameFormat, testName); 
       if (!File.Exists(filePath)) 
       { 
        Console.WriteLine("File {0} not exists", filePath); 
        return; 
       } 
       var success = setDevMode(printerName, filePath); 
       if(!success) 
       { 
        Console.WriteLine("Failed"); 
       } 
      } 
     } 

     private static void PrinterInfo() 
     { 
      Console.Write("Printer name: "); 
      string printerName = Console.ReadLine(); 

      IntPtr hDevMode;      // handle to the DEVMODE 
      IntPtr pDevMode;      // pointer to the DEVMODE 
      DEVMODE devMode;      // the actual DEVMODE structure 


      //var printController = new StandardPrintController(); 
      PrinterSettings printerSettings = new PrinterSettings(); 
      printerSettings.PrinterName = printerName; 


      // Get a handle to a DEVMODE for the default printer settings 
      hDevMode = printerSettings.GetHdevmode(printerSettings.DefaultPageSettings); 

      // Obtain a lock on the handle and get an actual pointer so Windows won't 
      // move it around while we're futzing with it 
      pDevMode = GlobalLock(hDevMode); 

      // Marshal the memory at that pointer into our P/Invoke version of DEVMODE 
      devMode = (DEVMODE)Marshal.PtrToStructure(pDevMode, typeof(DEVMODE)); 

      Dictionary<string, int> dmConstants = new Dictionary<string, int> 
                 { 
                  {"DM_ORIENTATION", 0x00000001}, 
                  {"DM_PAPERSIZE", 0x00000002}, 
                  {"DM_PAPERLENGTH", 0x00000004}, 
                  {"DM_PAPERWIDTH", 0x00000008}, 
                  {"DM_SCALE", 0x00000010}, 
                  {"DM_POSITION", 0x00000020}, 
                  {"DM_NUP", 0x00000040}, 
                  {"DM_DISPLAYORIENTATION", 0x00000080}, 
                  {"DM_COPIES", 0x00000100}, 
                  {"DM_DEFAULTSOURCE", 0x00000200}, 
                  {"DM_PRINTQUALITY", 0x00000400}, 
                  {"DM_COLOR", 0x00000800}, 
                  {"DM_DUPLEX", 0x00001000}, 
                  {"DM_YRESOLUTION", 0x00002000}, 
                  {"DM_TTOPTION", 0x00004000}, 
                  {"DM_COLLATE", 0x00008000}, 
                  {"DM_FORMNAME", 0x00010000}, 
                  {"DM_LOGPIXELS", 0x00020000}, 
                  {"DM_BITSPERPEL", 0x00040000}, 
                  {"DM_PELSWIDTH", 0x00080000}, 
                  {"DM_PELSHEIGHT", 0x00100000}, 
                  {"DM_DISPLAYFLAGS", 0x00200000}, 
                  {"DM_DISPLAYFREQUENCY", 0x00400000}, 
                  {"DM_ICMMETHOD", 0x00800000}, 
                  {"DM_ICMINTENT", 0x01000000}, 
                  {"DM_MEDIATYPE", 0x02000000}, 
                  {"DM_DITHERTYPE", 0x04000000}, 
                  {"DM_PANNINGWIDTH", 0x08000000}, 
                  {"DM_PANNINGHEIGHT", 0x10000000}, 
                  {"DM_DISPLAYFIXEDOUTPUT", 0x20000000}, 
                 }; 
      Console.WriteLine("Allow set: {0}. Details: {1}", Convert.ToString(devMode.dmFields, 16), string.Join(",", dmConstants.Where(c=>(devMode.dmFields & c.Value)==c.Value).Select(c=>c.Key))); 

      //private const int DM_POSITION = 0x00000020; 
      //private const int DM_NUP = 0x00000040; 
      //private const int DM_DISPLAYORIENTATION = 0x00000080; 
      //private const int DM_DEFAULTSOURCE = 0x00000200; 
      //private const int DM_PRINTQUALITY = 0x00000400; 
      //private const int DM_COLOR = 0x00000800; 
      //private const int DM_YRESOLUTION = 0x00002000; 
      //private const int DM_TTOPTION = 0x00004000; 
      //private const int DM_FORMNAME = 0x00010000; 
      //private const int DM_LOGPIXELS = 0x00020000; 
      //private const int DM_BITSPERPEL = 0x00040000; 
      //private const int DM_PELSWIDTH = 0x00080000; 
      //private const int DM_PELSHEIGHT = 0x00100000; 
      //private const int DM_DISPLAYFLAGS = 0x00200000; 
      //private const int DM_DISPLAYFREQUENCY = 0x00400000; 
      //private const int DM_ICMMETHOD = 0x00800000; 
      //private const int DM_ICMINTENT = 0x01000000; 
      //private const int DM_MEDIATYPE = 0x02000000; 
      //private const int DM_DITHERTYPE = 0x04000000; 
      //private const int DM_PANNINGWIDTH = 0x08000000; 
      //private const int DM_PANNINGHEIGHT = 0x10000000; 
      //private const int DM_DISPLAYFIXEDOUTPUT = 0x20000000; 

      WriteDevModePropertyInfo("DeviceName", devMode.dmDeviceName, null); 
      WriteDevModePropertyInfo("SpecVersion", devMode.dmSpecVersion.ToString(), null); 
      WriteDevModePropertyInfo("DriverVersion", devMode.dmDriverVersion.ToString(), null); 
      WriteDevModePropertyInfo("Size", devMode.dmSize.ToString(), null); 
      WriteDevModePropertyInfo("DriverExtra", devMode.dmDriverExtra.ToString(), null); 
      WriteDevModePropertyInfo("Orientation", devMode.dmOrientation.ToString(), (devMode.dmFields & DM_ORIENTATION) == DM_ORIENTATION); 
      WriteDevModePropertyInfo("PaperSize", devMode.dmPaperSize.ToString(), (devMode.dmFields & DM_PAPERSIZE) == DM_PAPERSIZE); 
      WriteDevModePropertyInfo("PaperLength", devMode.dmPaperLength.ToString(), (devMode.dmFields & DM_PAPERLENGTH) == DM_PAPERLENGTH); 
      WriteDevModePropertyInfo("PaperWidth", devMode.dmPaperWidth.ToString(), (devMode.dmFields & DM_PAPERWIDTH) == DM_PAPERWIDTH); 
      WriteDevModePropertyInfo("Scale", devMode.dmScale.ToString(), (devMode.dmFields & DM_SCALE) == DM_SCALE); 
      WriteDevModePropertyInfo("Copies", devMode.dmCopies.ToString(), (devMode.dmFields & DM_COPIES) == DM_COPIES); 
      WriteDevModePropertyInfo("Duplex", devMode.dmDuplex.ToString(), (devMode.dmFields & DM_DUPLEX) == DM_DUPLEX); 
      WriteDevModePropertyInfo("YResolution", devMode.dmYResolution.ToString(), null); 
      WriteDevModePropertyInfo("TTOption", devMode.dmTTOption.ToString(), null); 
      WriteDevModePropertyInfo("Collate", devMode.dmCollate.ToString(), (devMode.dmFields & DM_COLLATE) == DM_COLLATE); 
      WriteDevModePropertyInfo("FormName", devMode.dmFormName.ToString(), null); 
      WriteDevModePropertyInfo("UnusedPadding", devMode.dmUnusedPadding.ToString(), null); 
      WriteDevModePropertyInfo("BitsPerPel", devMode.dmBitsPerPel.ToString(), null); 
      WriteDevModePropertyInfo("PelsWidth", devMode.dmPelsWidth.ToString(), null); 
      WriteDevModePropertyInfo("PelsHeight", devMode.dmPelsHeight.ToString(), null); 
      WriteDevModePropertyInfo("DisplayFlags", devMode.dmDisplayFlags.ToString(), null); 
      WriteDevModePropertyInfo("DisplayFrequency", devMode.dmDisplayFlags.ToString(), null); 
     } 

     private static void WriteDevModePropertyInfo(string settingName, string value, bool? allowSet) 
     { 
      Console.WriteLine("{0} {1} {2}", allowSet.HasValue ? (allowSet.Value ? "+" : "-") : " ", settingName.PadRight(20, '.'), value); 
     } 


     [DllImport("kernel32.dll", ExactSpelling = true)] 
     public static extern IntPtr GlobalFree(IntPtr handle); 

     [DllImport("kernel32.dll", ExactSpelling = true)] 
     public static extern IntPtr GlobalLock(IntPtr handle); 

     [DllImport("kernel32.dll", ExactSpelling = true)] 
     public static extern IntPtr GlobalUnlock(IntPtr handle); 

     [DllImport("kernel32.dll", EntryPoint = "GetLastError", SetLastError = false, 
      ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     private static extern Int32 GetLastError(); 

     [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, 
      ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     private static extern bool ClosePrinter(IntPtr hPrinter); 

     [DllImport("winspool.Drv", EntryPoint = "DocumentPropertiesA", SetLastError = true, 
      ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     private static extern int DocumentProperties(IntPtr hwnd, IntPtr hPrinter, 
                [MarshalAs(UnmanagedType.LPStr)] string pDeviceNameg, 
                IntPtr pDevModeOutput, ref IntPtr pDevModeInput, int fMode); 

     [DllImport("winspool.Drv", EntryPoint = "GetPrinterA", SetLastError = true, 
      CharSet = CharSet.Ansi, ExactSpelling = true, 
      CallingConvention = CallingConvention.StdCall)] 
     private static extern bool GetPrinter(IntPtr hPrinter, Int32 dwLevel, 
               IntPtr pPrinter, Int32 dwBuf, out Int32 dwNeeded); 

     [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", 
      SetLastError = true, CharSet = CharSet.Ansi, 
      ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     private static extern bool 
      OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, 
         out IntPtr hPrinter, ref PRINTER_DEFAULTS pd); 

     [DllImport("winspool.drv", CharSet = CharSet.Ansi, SetLastError = true)] 
     private static extern bool SetPrinter(IntPtr hPrinter, int Level, IntPtr 
                       pPrinter, int Command); 

     [DllImport("kernel32.dll")] 
     static extern IntPtr GlobalAlloc(uint uFlags, int dwBytes); 

     public static void getDevMode(string printerName, string filepath) 
     { 
      PRINTER_DEFAULTS PrinterValues = new PRINTER_DEFAULTS(); 
      PrinterValues.pDatatype = 0; 
      PrinterValues.pDevMode = 0; 
      PrinterValues.DesiredAccess = PRINTER_ALL_ACCESS; 

      IntPtr ptrZero = IntPtr.Zero; 
      IntPtr hPrinter; 
      IntPtr pDevMode = new IntPtr(); 

      //get printer handle 
      OpenPrinter(printerName, out hPrinter, ref PrinterValues); 

      //allocate memory for ptr to devmode, 0 argument retrieves bytes required 
      int bytes = DocumentProperties(new IntPtr(0), hPrinter, printerName, ptrZero, ref pDevMode, 0); 
      pDevMode = GlobalAlloc(0, bytes); 

      //set the pointer 
      DocumentProperties(new IntPtr(0), hPrinter, printerName, pDevMode, ref ptrZero, DM_OUT_BUFFER); 

      //write the devMode to a file 
      using (FileStream fs = new FileStream(filepath, FileMode.Create)) 
      { 
       for (int i = 0; i < bytes; i++) 
       { 
        fs.WriteByte(Marshal.ReadByte(pDevMode, i)); 
       } 
      } 
      //free resources 
      GlobalFree(pDevMode); 
      ClosePrinter(hPrinter); 
     } 

     public static bool setDevMode(string printerName, string filepath) 
     { 
      if(!File.Exists(filepath)) 
      { 
       return false; 
      } 

      IntPtr hPrinter; 
      int bytes = 0; 
      IntPtr pPInfo; 
      IntPtr pDevMode; 
      PRINTER_INFO_2 pInfo = new PRINTER_INFO_2(); 

      PRINTER_DEFAULTS PrinterValues = new PRINTER_DEFAULTS(); 
      PrinterValues.pDatatype = 0; 
      PrinterValues.pDevMode = 0; 
      PrinterValues.DesiredAccess = PRINTER_ALL_ACCESS; 

      //retrieve the devmode from file 
      using (FileStream fs = new FileStream(filepath, FileMode.Open)) 
      { 
       int length = Convert.ToInt32(fs.Length); 
       pDevMode = GlobalAlloc(0, length); 
       for (int i = 0; i < length; i++) 
       { 
        Marshal.WriteByte(pDevMode, i, (byte)fs.ReadByte()); 
       } 
      } 

      //get printer handle 
      OpenPrinter(printerName, out hPrinter, ref PrinterValues); 

      //get bytes for printer info structure and allocate memory 
      GetPrinter(hPrinter, 2, IntPtr.Zero, 0, out bytes); 
      if (bytes == 0) 
      { 
       throw new Exception("Get Printer Failed"); 
      } 
      pPInfo = GlobalAlloc(0, bytes); 

      //set pointer to printer info 
      GetPrinter(hPrinter, 2, pPInfo, bytes, out bytes); 

      //place the printer info structure 
      pInfo = (PRINTER_INFO_2)Marshal.PtrToStructure(pPInfo, typeof(PRINTER_INFO_2)); 

      //insert the new devmode 
      pInfo.pDevMode = pDevMode; 
      pInfo.pSecurityDescriptor = IntPtr.Zero; 

      //set pointer to new printer info 
      Marshal.StructureToPtr(pInfo, pPInfo, true); 

      //update 
      SetPrinter(hPrinter, 2, pPInfo, 0); 

      //free resources 
      GlobalFree(pPInfo); 
      GlobalFree(pDevMode); 
      ClosePrinter(hPrinter); 

      return true; 
     } 

     private static void PrintWordDocument(string path, string printerName) 
     { 
      object readOnly = true; 
      object addToRecentFiles = false; 
      object visible = false; 
      object backgroundPrint = false; 
      object saveChanges = false; 
      object sourceFile = path; 

      var wordApplication = new Application(); 
      var doc = wordApplication.Documents.OpenNoRepairDialog(FileName: ref sourceFile, ReadOnly: ref readOnly, 
                   AddToRecentFiles: ref addToRecentFiles, 
                   Visible: ref visible); 
      wordApplication.ActivePrinter = printerName; 
      doc.Activate(); 
      wordApplication.PrintOut(Background: ref backgroundPrint, FileName: sourceFile); 
      object _missing = Type.Missing; 
      doc.Close(ref saveChanges, ref _missing, ref _missing); 
     } 
    } 
} 
+0

正如我已經說過這個答案不理想。所以如果有人有更好的方法,請歡迎發佈。 –