700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 使用C#更改打印机驱动打印属性设置

使用C#更改打印机驱动打印属性设置

时间:2023-07-09 18:03:10

相关推荐

使用C#更改打印机驱动打印属性设置

更多源码参考,可参考本人csdn下载空间(/detail/kingmax5421/9881707)。或联系本人:kingmax5421@

介绍

为应用程序打印MS Word文档,并且应该给用户一个选项来更改他/她想要打印的文档的打印机设置,以便用户可以更改打印机的页面源和双面打印属性。

当我们开始将代码转换为C#时,我发现MS Word API中没有功能来更改打印机的双面打印属性。Word在WordApplication类'PrintOut方法中提供了一个参数,但是Microsoft建议不要使用它,因为它是操作系统和语言相关的。

真正令人担忧的是.NET中的打印库。我没有找到任何可以更改打印机设置的类PrintDocument与它相关联。我真的觉得.NET应该提供类来更改打印机设置,或者为此,.NET应该提供了一个库,它有助于防止开发人员使用依赖于操作系统的WIN API(最终在设计打印机类中这是OS独立的)。

另一个问题是,OpenPrinter不适用于网络打印机(虽然Microsoft建议设置打印机的方式,我不能对客户端做同样的事情)。有趣的部分是VB6代码没有任何问题(访问被拒绝)工作,所有MS Office工具都可以正常工作,那为什么不是C#代码?

以下是全局更改打印机设置的C#代码。这只是一个示例代码。请原谅我,因为代码不是优雅的,唯一的意图是解释它是如何工作的。代码不适用于网络打印机。有关设置网络打印机的更多信息,请参阅以下链接。

MSDN 隐藏收缩复制代码

public class PrinterSettings {#region "Private Variables"private IntPtr hPrinter = new System.IntPtr() ;private PRINTER_DEFAULTS PrinterValues = new PRINTER_DEFAULTS();private PRINTER_INFO_2 pinfo = new PRINTER_INFO_2();private DEVMODE dm;private IntPtr ptrDM;private IntPtr ptrPrinterInfo;private int sizeOfDevMode = 0;private int lastError;private int nBytesNeeded;private long nRet; private int intError;private System.Int32 nJunk;private IntPtr yDevModeData;#endregion#region "Win API Def"[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)]static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, ref PRINTER_DEFAULTS pd)[ DllImport( "winspool.drv",CharSet=CharSet.Unicode,ExactSpelling=false,CallingConvention=CallingConvention.StdCall )]public static extern long OpenPrinter(string pPrinterName, ref IntPtr phPrinter, int pDefault);*//*[DllImport("winspool.Drv", EntryPoint="OpenPrinterA", SetLastError=true, CharSet=CharSet.Ansi, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, ref PRINTER_DEFAULTS pd);*/ [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("winspool.drv", CharSet=CharSet.Ansi, SetLastError=true)]private static extern bool SetPrinter(IntPtr hPrinter, int Level, IntPtr pPrinter, int Command);*/// Wrapper for Win32 message formatter./*[DllImport("kernel32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)]private unsafe static extern int FormatMessage( int dwFlags,ref IntPtr pMessageSource,int dwMessageID,int dwLanguageID,ref string lpBuffer,int nSize,IntPtr* pArguments);*/#endregion#region "Data structure"[StructLayout(LayoutKind.Sequential)]public struct PRINTER_DEFAULTS{public int pDatatype;public int pDevMode;public int DesiredAccess;}/*[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]public struct PRINTER_DEFAULTS{public int pDataType;public IntPtr pDevMode;public ACCESS_MASK DesiredAccess;}*/[StructLayout(LayoutKind.Sequential)]private struct PRINTER_INFO_2{[MarshalAs(UnmanagedType.LPStr)] public string pServerName; [MarshalAs(UnmanagedType.LPStr)] public string pPrinterName; [MarshalAs(UnmanagedType.LPStr)] public string pShareName; [MarshalAs(UnmanagedType.LPStr)] public string pPortName; [MarshalAs(UnmanagedType.LPStr)] public string pDriverName; [MarshalAs(UnmanagedType.LPStr)] public string pComment; [MarshalAs(UnmanagedType.LPStr)] public string pLocation; public IntPtr pDevMode; [MarshalAs(UnmanagedType.LPStr)] public string pSepFile; [MarshalAs(UnmanagedType.LPStr)] public string pPrintProcessor; [MarshalAs(UnmanagedType.LPStr)] public string pDatatype; [MarshalAs(UnmanagedType.LPStr)] public string pParameters; public IntPtr pSecurityDescriptor; public Int32 Attributes; public Int32 Priority; public Int32 DefaultPriority; public Int32 StartTime; public Int32 UntilTime; public Int32 Status; public Int32 cJobs; public Int32 AveragePPM; }private const short CCDEVICENAME = 32;private const short CCFORMNAME = 32;[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;}#endregion#region "Constants"private const int DM_DUPLEX = 0x1000;private const int DM_IN_BUFFER = 8;private const int DM_OUT_BUFFER = 2;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);#endregion#region "Function to change printer settings" public bool ChangePrinterSetting(string PrinterName,PrinterData PS){if (((int)PS.Duplex < 1) || ((int)PS.Duplex > 3) ){throw new ArgumentOutOfRangeException("nDuplexSetting","nDuplexSetting is incorrect.");}else{dm = this.GetPrinterSettings( PrinterName);dm.dmDefaultSource =(short)PS.source; dm.dmOrientation = (short)PS.Orientation; dm.dmPaperSize =(short)PS.Size;dm.dmDuplex = (short)PS.Duplex; Marshal.StructureToPtr( dm,yDevModeData,true); pinfo.pDevMode = yDevModeData;pinfo.pSecurityDescriptor = IntPtr.Zero;/*update driver dependent part of the DEVMODE1 = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName, yDevModeData, ref pinfo.pDevMode, (DM_IN_BUFFER | DM_OUT_BUFFER));*/Marshal.StructureToPtr(pinfo,ptrPrinterInfo,true); lastError = Marshal.GetLastWin32Error();nRet = Convert.ToInt16(SetPrinter(hPrinter, 2, ptrPrinterInfo, 0));if (nRet == 0){//Unable to set shared printer settings.lastError = Marshal.GetLastWin32Error();//string myErrMsg = GetErrorMessage(lastError);throw new Win32Exception(Marshal.GetLastWin32Error()); }if (hPrinter != IntPtr.Zero) ClosePrinter(hPrinter);return Convert.ToBoolean(nRet);}}private DEVMODE GetPrinterSettings(string PrinterName){PrinterData PData = new PrinterData(); DEVMODE dm;const int PRINTER_ACCESS_ADMINISTER = 0x4;const int PRINTER_ACCESS_USE = 0x8;const int PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE);PrinterValues.pDatatype =0;PrinterValues.pDevMode = 0 ;PrinterValues.DesiredAccess = PRINTER_ALL_ACCESS;nRet = Convert.ToInt32(OpenPrinter(PrinterName, out hPrinter, ref PrinterValues));if (nRet == 0){lastError = Marshal.GetLastWin32Error();throw new Win32Exception(Marshal.GetLastWin32Error()); }GetPrinter(hPrinter, 2, IntPtr.Zero, 0, out nBytesNeeded);if (nBytesNeeded <= 0){throw new System.Exception("Unable to allocate memory");}else{// Allocate enough space for PRINTER_INFO_2... {ptrPrinterIn fo = Marshal.AllocCoTaskMem(nBytesNeeded)};ptrPrinterInfo = Marshal.AllocHGlobal(nBytesNeeded);// The second GetPrinter fills in all the current settings, so all you // need to do is modify what you're interested in...nRet = Convert.ToInt32(GetPrinter(hPrinter, 2, ptrPrinterInfo, nBytesNeeded, out nJunk));if (nRet == 0){lastError = Marshal.GetLastWin32Error();throw new Win32Exception(Marshal.GetLastWin32Error()); }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 structuresizeOfDevMode = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, ptrZero, ref ptrZero, 0);ptrDM = Marshal.AllocCoTaskMem(sizeOfDevMode);int i ;i = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, ptrDM, ref ptrZero, DM_OUT_BUFFER);if ((i < 0) || (ptrDM == IntPtr.Zero)){//Cannot get the DEVMODE structure.throw new System.Exception("Cannot get DEVMODE data"); }pinfo.pDevMode = ptrDM;}intError = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, IntPtr.Zero , ref Temp , 0);//IntPtr yDevModeData = Marshal.AllocCoTaskMem(i1);yDevModeData= Marshal.AllocHGlobal(intError);intError = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, yDevModeData , ref Temp , 2);dm = (DEVMODE)Marshal.PtrToStructure(yDevModeData, typeof(DEVMODE));//nRet = DocumentProperties(IntPtr.Zero, hPrinter, sPrinterName, yDevModeData// , ref yDevModeData, (DM_IN_BUFFER | DM_OUT_BUFFER));if ((nRet == 0) || (hPrinter == IntPtr.Zero)){lastError = Marshal.GetLastWin32Error();//string myErrMsg = GetErrorMessage(lastError);throw new Win32Exception(Marshal.GetLastWin32Error()); }return dm;}#endregion}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。