/// <summary>
        /// Method Name : GetPrinterDuplex
        /// Programmatically get the Duplex flag for the specified printer
        /// driver's default properties.
        /// </summary>
        /// <param name="sPrinterName"> The name of the printer to be used. </param>
        /// <param name="errorMessage"> this will contain error messsage if any. </param>
        /// <returns>
        /// nDuplexSetting - One of the following standard settings:
        /// 0 = Error
        /// 1 = None (Simplex)
        /// 2 = Duplex on long edge (book)
        /// 3 = Duplex on short edge (legal)
        /// </returns>
        /// <remarks>
        /// </remarks>
        public short GetPrinterDuplex(string sPrinterName, out string errorMessage)
        {
            errorMessage = string.Empty;
            short            functionReturnValue = 0;
            IntPtr           hPrinter            = default(IntPtr);
            PRINTER_DEFAULTS pd = default(PRINTER_DEFAULTS);
            DEVMODE          dm = new DEVMODE();
            int nRet            = 0;

            pd.DesiredAccess = PRINTER_ACCESS_USE;
            nRet             = OpenPrinter(sPrinterName, out hPrinter, ref pd);
            if ((nRet == 0) | (hPrinter.ToInt32() == 0))
            {
                if (GetLastError() == 5)
                {
                    errorMessage = "Access denied -- See the article for more info.";
                }
                else
                {
                    errorMessage = "Cannot open the printer specified " + "(make sure the printer name is correct).";
                }
                return(functionReturnValue);
            }
            nRet = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName, IntPtr.Zero, IntPtr.Zero, 0);
            if ((nRet < 0))
            {
                errorMessage = "Cannot get the size of the DEVMODE structure.";
                goto cleanup;
            }
            IntPtr iparg = Marshal.AllocCoTaskMem(nRet + 100);

            nRet = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName, iparg, IntPtr.Zero, DM_OUT_BUFFER);
            if ((nRet < 0))
            {
                errorMessage = "Cannot get the DEVMODE structure.";
                goto cleanup;
            }
            dm = (DEVMODE)Marshal.PtrToStructure(iparg, dm.GetType());
            if (!Convert.ToBoolean(dm.dmFields & DM_DUPLEX))
            {
                errorMessage = "You cannot modify the duplex flag for this printer " + "because it does not support duplex or the driver " + "does not support setting it from the Windows API.";
                goto cleanup;
            }
            functionReturnValue = dm.dmDuplex;

cleanup:
            if ((hPrinter.ToInt32() != 0))
            {
                ClosePrinter(hPrinter);
            }
            return(functionReturnValue);
        }
        /// <summary>
        /// Method Name : SetPrinterDuplex
        /// Programmatically set the Duplex flag for the specified printer driver's default properties.
        /// </summary>
        /// <param name="sPrinterName"> sPrinterName - The name of the printer to be used. </param>
        /// <param name="nDuplexSetting">
        /// nDuplexSetting - One of the following standard settings:
        /// 1 = None
        /// 2 = Duplex on long edge (book)
        /// 3 = Duplex on short edge (legal)
        /// </param>
        ///  <param name="errorMessage"> this will contain error messsage if any. </param>
        /// <returns>
        /// Returns: True on success, False on error.
        /// </returns>
        /// <remarks>
        ///
        /// </remarks>
        public bool SetPrinterDuplex(string sPrinterName, int nDuplexSetting, out string errorMessage)
        {
            errorMessage = string.Empty;
            bool             functionReturnValue = false;
            IntPtr           hPrinter            = default(IntPtr);
            PRINTER_DEFAULTS pd             = default(PRINTER_DEFAULTS);
            PRINTER_INFO_9   pinfo          = new PRINTER_INFO_9();
            DEVMODE          dm             = new DEVMODE();
            IntPtr           ptrPrinterInfo = default(IntPtr);
            int   nBytesNeeded = 0;
            int   nRet         = 0;
            Int32 nJunk        = default(Int32);

            if ((nDuplexSetting < 1) | (nDuplexSetting > 3))
            {
                errorMessage = "Error: dwDuplexSetting is incorrect.";
                return(functionReturnValue);
            }
            pd.DesiredAccess = PRINTER_ACCESS_USE;
            nRet             = OpenPrinter(sPrinterName, out hPrinter, ref pd);
            if ((nRet == 0) | (hPrinter.ToInt32() == 0))
            {
                if (GetLastError() == 5)
                {
                    errorMessage = "Access denied -- See the article for more info.";
                }
                else
                {
                    errorMessage = "Cannot open the printer specified " + "(make sure the printer name is correct).";
                }
                return(functionReturnValue);
            }
            nRet = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName, IntPtr.Zero, IntPtr.Zero, 0);
            if ((nRet < 0))
            {
                errorMessage = "Cannot get the size of the DEVMODE structure.";
                goto cleanup;
            }
            IntPtr iparg = Marshal.AllocCoTaskMem(nRet + 100);

            nRet = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName, iparg, IntPtr.Zero, DM_OUT_BUFFER);
            if ((nRet < 0))
            {
                errorMessage = "Cannot get the DEVMODE structure.";
                goto cleanup;
            }
            dm = (DEVMODE)Marshal.PtrToStructure(iparg, dm.GetType());
            if (!Convert.ToBoolean(dm.dmFields & DM_DUPLEX))
            {
                errorMessage = "You cannot modify the duplex flag for this printer " + "because it does not support duplex or the driver " + "does not support setting it from the Windows API.";
                goto cleanup;
            }
            dm.dmDuplex = (short)nDuplexSetting;
            Marshal.StructureToPtr(dm, iparg, true);
            nRet = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName, pinfo.pDevMode, pinfo.pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);
            if ((nRet < 0))
            {
                errorMessage = "Unable to set duplex setting to this printer.";
                goto cleanup;
            }
            GetPrinter(hPrinter, 9, IntPtr.Zero, 0, ref nBytesNeeded);
            if ((nBytesNeeded == 0))
            {
                errorMessage = "GetPrinter failed.";
                goto cleanup;
            }
            ptrPrinterInfo = Marshal.AllocCoTaskMem(nBytesNeeded + 100);
            nRet           = GetPrinter(hPrinter, 9, ptrPrinterInfo, nBytesNeeded, ref nJunk) ? 1 : 0;
            if ((nRet == 0))
            {
                errorMessage = "Unable to get shared printer settings.";
                goto cleanup;
            }
            pinfo                     = (PRINTER_INFO_9)Marshal.PtrToStructure(ptrPrinterInfo, pinfo.GetType());
            pinfo.pDevMode            = iparg;
            pinfo.pSecurityDescriptor = 0;
            Marshal.StructureToPtr(pinfo, ptrPrinterInfo, true);
            nRet = SetPrinter(hPrinter, 9, ptrPrinterInfo, 0) ? 1 : 0;
            if ((nRet == 0))
            {
                errorMessage = "Unable to set shared printer settings.";
            }
            functionReturnValue = Convert.ToBoolean(nRet);
cleanup:
            if ((hPrinter.ToInt32() != 0))
            {
                ClosePrinter(hPrinter);
            }
            return(functionReturnValue);
        }
Beispiel #3
0
    /// <summary>
    /// 改变打印机的设置
    /// 张刊
    /// 2016年8月18日
    /// [email protected]
    /// </summary>
    /// <param name="PrinterName">打印机名称,如果为空则使用默认打印机</param>
    /// <param name="PS">需要改变的信息</param>
    /// <returns>是否改变成功</returns>
    public static void ModifyPrintInfo2(string PrinterName, ref PrinterData PS)
    {
        PRINTER_INFO_9 printerInfo;

        printerInfo.pDevMode = IntPtr.Zero;
        if (PrinterName == string.Empty || PrinterName == null)
        {
            PrinterName = GetDeaultPrinterName();
        }
        pd.pDatatype     = 0;
        pd.pDevMode      = 0;
        pd.DesiredAccess = PRINTER_ALL_ACCESS;
        if (OpenPrinter(PrinterName, out hPrinter, ref pd))
        {
            try
            {
                //得到结构体DEVMODE的大小
                int iDevModeSize = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, IntPtr.Zero, IntPtr.Zero, 0);
                if (iDevModeSize < 0)
                {
                    throw new ApplicationException("Cannot get the size of the DEVMODE structure.");
                }
                //分配指向结构体DEVMODE的内存缓冲区
                IntPtr hDevMode = Marshal.AllocCoTaskMem(iDevModeSize + 100);
                //得到一个指向DEVMODE内存缓存的指针
                nRet = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, hDevMode, IntPtr.Zero, DM_OUT_BUFFER);
                if (nRet < 0)
                {
                    throw new ApplicationException("Cannot get the size of the DEVMODE structure.");
                }
                //給dm賦值
                dm = (DEVMODE)Marshal.PtrToStructure(hDevMode, dm.GetType());

                if ((((int)PS.Duplex < 0) || ((int)PS.Duplex > 3)))
                {
                    throw new ArgumentOutOfRangeException("nDuplexSetting", "nDuplexSetting is incorrect.");
                }
                else
                {
                    //更改printersetting
                    if ((int)PS.Size != 0)
                    {
                        dm.dmPaperSize = (short)PS.Size;
                        dm.dmFields   |= DM_PAPERSIZE;
                    }
                    if (PS.pWidth != 0)
                    {
                        dm.dmPaperWidth = (short)PS.pWidth;
                        dm.dmFields    |= DM_PAPERWIDTH;
                    }
                    if (PS.pLength != 0)
                    {
                        dm.dmPaperLength = (short)PS.pLength;
                        dm.dmFields     |= DM_PAPERLENGTH;
                    }
                    if (PS.pFormName != null && PS.pFormName != string.Empty)
                    {
                        dm.dmFormName = PS.pFormName;
                        dm.dmFields  |= DM_FORMNAME;
                    }
                    if ((int)PS.Orientation != 0)
                    {
                        dm.dmOrientation = (short)PS.Orientation;
                        dm.dmFields     |= DM_ORIENTATION;
                    }
                    Marshal.StructureToPtr(dm, hDevMode, true);

                    //                        pinfo.pDevMode = hDevMode;
                    //                        pinfo.pSecurityDescriptor = IntPtr.Zero;
                    //                        /*update driver dependent part of the DEVMODE
                    //                        1 = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName, yDevModeData, ref pinfo.pDevMode, (DM_IN_BUFFER | DM_OUT_BUFFER));*/
                    //                        Marshal.StructureToPtr(pinfo,ptrPrinterInfo,true);
                    //得到printer info的大小
                    nRet = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, printerInfo.pDevMode, printerInfo.pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);
                    if (nRet < 0)
                    {
                        throw new ApplicationException("Unable to set the PrintSetting for this printer");
                    }
                    GetPrinter(hPrinter, 9, IntPtr.Zero, 0, out nBytesNeeded);
                    if (nBytesNeeded == 0)
                    {
                        throw new ApplicationException("GetPrinter failed.Couldn't get the nBytesNeeded for shared PRINTER_INFO_9 structure");
                    }
                    //分配内存缓冲区大小
                    ptrPrinterInfo = Marshal.AllocCoTaskMem(nBytesNeeded);
                    bool bSuccess = GetPrinter(hPrinter, 9, ptrPrinterInfo, nBytesNeeded, out nJunk);
                    if (!bSuccess)
                    {
                        throw new ApplicationException("GetPrinter failed.Couldn't get the nBytesNeeded for shared PRINTER_INFO_9 structure");
                    }
                    //赋值printerInfo
                    printerInfo          = (PRINTER_INFO_9)Marshal.PtrToStructure(ptrPrinterInfo, printerInfo.GetType());
                    printerInfo.pDevMode = hDevMode;

                    //获取一个指向 PRINTER_INFO_9结构的指针
                    Marshal.StructureToPtr(printerInfo, ptrPrinterInfo, true);
                    //设置打印机
                    bSuccess = SetPrinter(hPrinter, 9, ptrPrinterInfo, 0);
                    if (!bSuccess)
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error(), "SetPrinter() failed.Couldn't set the printer settings");
                    }

                    PrinterSetting.SendMessageTimeout(new IntPtr(HWND_BROADCAST), WM_SETTINGCHANGE, IntPtr.Zero, IntPtr.Zero, PrinterSetting.SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out hDummy);
                }
            }
            finally
            {
                ClosePrinter(hPrinter);
            }
        }
    }