本文介绍了使用高级选项打印(纸盒选择,双面打印,装订)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有管理打印文档的一个项目。起初,我不知道为什么打印选项不能成立单一的地方。例如打印机纸盒选择作为第一页和其他页面是可以做到的微软Word自动化

We have a project of managing printing documents. At first I wonder why printing options couldn't be set up in single place. For example printer tray selection for first page and for other pages can be done using MS Word automation:

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);

在code打印机纸盒上面指定为整数,因为某些打印机有托盘没有非标准值(我们有这个问题,惠普 - 这是盘codeS描述这里)。所以,我们首先检索什么托盘打印机有,使用code:

In the code above printer tray is specified as integer because some printers have not standart values for trays (we had this issue with HP - it's tray codes described here). So we first retrieve what trays printer have, using code:

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

这code工作没有问题。

And this code works with no problems.

但也没办法在这里指定双面打印和装订选项。 复式可以做,用的驱动函数OpenPrinter和SetPrinter ,像描述的,并建议微软以及中的。短纤完全不清楚如果有人知道的方式如何实现这一点,请让我知道。在这个MSDN文章是没用的因为它需要的文件的定制渲染打印。

But there is no way to specify duplex and staple options here. Duplex can be done, using driver functions OpenPrinter and SetPrinter, like described here and recommended by Microsoft as well in this forum thread.Staple is completely unclear and if somebody knows by the way how to implement this, please let me know. Using Stapling enum, like in this MSDN article is useless as it requires custom rendering of the document to print.

我描述的情况,以及如何零部件实施的。 这正常工作对环境的:在Windows Server 2008 R2,微软Office 2010的32倍,打印机的HP LaserJet P2055和理光Nashuatec DSm635。测试与本地和通用PCL6 /的PCL5e驱动程序:双工和预期纸盒选择适用

I described the situation and how parts were implemented. That works fine on our environment: Windows Server 2008 R2, MS Office 2010 x32, Printers HP LaserJet P2055 and Ricoh Nashuatec DSm635. Tested with native and universal PCL6/PCL5e drivers: duplex and tray selection works as expected.

但是部署应用程序客户端后,的,打印机(仅限HP LaserJet 4250和理光Aficio MP C7501)的做印花总是从默认纸盒和双面无。尝试一些不同的驱动程序具有完全相同的结果。

But after deployment the application to client, printers (HP LaserJet 4250 and Ricoh Aficio MP C7501) do printing always from default tray and without duplex. Tried few different drivers with exactly the same result.

在这两种环境中打印机是网络打印机。因此,为了使它们应用于双工设置,使用打印机驱动程序,我们需要在服务器上安装本地驱动程序,使本地打印机,建议我在微软的。

In both environments printers are network printers. So to make them apply duplex setting, using printer driver, we needed to install local driver on server and make a local printer, as recommended my Microsoft on this support forum thread.

虽然使用环境和打印机看起来非常相似,一期工程而其他没有。任何帮助将是非常美联社preciated。

Though environments and printers used looks very similar, one works while other do not. Any help will be highly appreciated.

推荐答案

在情况下,其他人需要它,我想出了一个解决方法,基于存储在二进制文件中打​​印机设置内存块,然后还原它。这个想法在这个博客帖子,但它并没有为我工作时,只需复制粘贴(只工作了一些司机和一些设置,而其他打印选项被忽略)。

In case someone else needs it, I came up with a workaround, based on storing printer settings memory block in a binary file and then restoring it. The idea was described in this blog post, but it didn't work for me when simply copy-pasted (it worked only for some drivers and for some settings while other printing options were ignored).

所以我改过后了一点,所以现在它可以支持我测试过我试过在任何打印机上的所有设置(与兼容的驱动程序)。当然,如果你使用其他打印机司机例如,它不会工作。

So I remade it a bit so that now it can support all settings I've tried on any printer (with compatible driver) I've tested. Of course if you use driver of another printer for example it won't work.

THI方法的缺点是当然,你应该先设置默认打印机,preferences(控制面板)到你所需要的。这并不总是可能的,当然,但至少在某些情况下,它可以帮助

The disadvantage of thi approach is of course that you should first set default printer preferences (in Control Panel) to what you need. That isn't always possible of course, but at least in some cases it can help.

所以测试util的是能够给打印机设置保存到一个文件的完整源$ C ​​$ C,使用指定的设置文件重新加载此文件到打印机并打印文档:

So the full source code of a test util which is capable to store printer settings into a file, load this file again into printer and print a document using the specified settings file:

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);
        }
    }
}

这篇关于使用高级选项打印(纸盒选择,双面打印,装订)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 02:18
查看更多