/// <summary> /// 改变打印机的设置 /// 张刊 /// 2016年8月18日 /// [email protected] /// </summary> /// <param name="PrinterName">打印机名称,如果为空则使用默认打印机</param> /// <param name="PS">需要改变的信息</param> /// <returns>是否改变成功</returns> public static bool ModifyPrintInfo3(string PrinterName, ref PrinterData PS) { pd.pDatatype = 0; pd.pDevMode = 0; pd.DesiredAccess = PRINTER_ALL_ACCESS; if (PrinterName == string.Empty || PrinterName == null) { PrinterName = GetDeaultPrinterName(); } nRet = Convert.ToInt32(OpenPrinter(PrinterName, out hPrinter, ref pd)); if (nRet == 0) { lastError = Marshal.GetLastWin32Error(); throw new Win32Exception(Marshal.GetLastWin32Error()); } //调用GetPrinter获取PRINTER_INFO_2在内存的字节数 GetPrinter(hPrinter, 2, IntPtr.Zero, 0, out nBytesNeeded); if (nBytesNeeded <= 0) { ClosePrinter(hPrinter); return(false); } //为PRINTER_INFO_2分配足够的内存 ptrPrinterInfo = Marshal.AllocHGlobal(nBytesNeeded); if (ptrPrinterInfo == IntPtr.Zero) { ClosePrinter(hPrinter); return(false); } //调用GetPrinter填充当前设定,所要改变的信息(ptrPrinterInfo中) if (!GetPrinter(hPrinter, 2, ptrPrinterInfo, nBytesNeeded, out nBytesNeeded)) { Marshal.FreeHGlobal(ptrPrinterInfo); ClosePrinter(hPrinter); return(false); } //把内存中指向PRINTER_INFO_2的指针转化为PRINTER_INFO_2结构 //如果GetPrinter没有得到DEVMODE结构,尝试调用DocumentProperties得到DEVMODE结构 pinfo = (PRINTER_INFO_2)Marshal.PtrToStructure(ptrPrinterInfo, typeof(PRINTER_INFO_2)); IntPtr Temp = new IntPtr(); if (pinfo.pDevMode == IntPtr.Zero) { // If GetPrinter didn't fill in the DEVMODE, try to get it by calling // DocumentProperties... IntPtr ptrZero = IntPtr.Zero; //get the size of the devmode structure nBytesNeeded = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, IntPtr.Zero, IntPtr.Zero, 0); if (nBytesNeeded <= 0) { Marshal.FreeHGlobal(ptrPrinterInfo); ClosePrinter(hPrinter); return(false); } ptrDM = Marshal.AllocCoTaskMem(nBytesNeeded); int i; i = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, ptrDM, ptrZero, DM_OUT_BUFFER); if ((i < 0) || (ptrDM == IntPtr.Zero)) { //Cannot get the DEVMODE structure. Marshal.FreeHGlobal(ptrDM); ClosePrinter(ptrPrinterInfo); return(false); } pinfo.pDevMode = ptrDM; } dm = (DEVMODE)Marshal.PtrToStructure(pinfo.pDevMode, typeof(DEVMODE)); //修改打印机的设定信息 if ((((int)PS.Duplex < 0) || ((int)PS.Duplex > 3))) { throw new ArgumentOutOfRangeException("nDuplexSetting", "nDuplexSetting is incorrect."); } else { if (PrinterName == string.Empty || PrinterName == null) { PrinterName = GetDeaultPrinterName(); } 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, pinfo.pDevMode, true); Marshal.StructureToPtr(pinfo, ptrPrinterInfo, true); pinfo.pSecurityDescriptor = IntPtr.Zero; //Make sure the driver_Dependent part of devmode is updated... nRet = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, pinfo.pDevMode, pinfo.pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER); if (nRet <= 0) { Marshal.FreeHGlobal(ptrPrinterInfo); ClosePrinter(hPrinter); return(false); } //SetPrinter 更新打印机信息 if (!SetPrinter(hPrinter, 2, ptrPrinterInfo, 0)) { Marshal.FreeHGlobal(ptrPrinterInfo); ClosePrinter(hPrinter); return(false); } //通知其他应用程序,打印机信息已经更改 PrinterSetting.SendMessageTimeout(new IntPtr(HWND_BROADCAST), WM_SETTINGCHANGE, IntPtr.Zero, IntPtr.Zero, PrinterSetting.SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out hDummy); //释放 if (ptrPrinterInfo == IntPtr.Zero) { Marshal.FreeHGlobal(ptrPrinterInfo); } if (hPrinter == IntPtr.Zero) { Marshal.FreeHGlobal(hPrinter); } return(true); } }
/// <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); } } }