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