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

更多源码参考,可参考本人csdn下载空间(http://download.csdn.net/detail/kingmax54212008/9881707)。或联系本人:kingmax5421@gmail.com

介绍

为应用程序打印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 DEVMODE
1 = 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 structure
sizeOfDevMode = 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
}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/255206.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

A4纸张缩印怎么只打印一半A4纸的内容

A4纸张的规格:210mmx297mm&#xff08;参考文章2&#xff09; 21cmx29.7cm A4纸张一半的长度 差不多 是 15cm&#xff0c;如下图所示&#xff0c;设置 页边距。打印即可 参考文章&#xff1a; 1. world文档怎么缩印&#xff08;如何打小抄&#xff09; 2.A4纸 3. 4.

计算机图桌面打印出来,电脑excel图片无法打印怎么处理

电脑excel图片无法打印怎么处理 excel是我们常用的数据编辑工具但是当我们需要打印的时候有可能出现图片无法打印的情况继续编就教大家怎么处理 具体如下: 1. 首先我们在桌面上找到需要进行处理的excel图标点击打开 2. 进入到表格界面之后我们点击表格最上方的打印预览图标然后…

关于windows XP下北洋BTP-2200E打印设置问题

&#xff08;1&#xff09;操作使用手册&#xff1a;http://www.chongshang.com.cn/manual/m_BTP2200E.shtml &#xff08;2&#xff09;驱动安装&#xff1a;http://www.chongshang.com.cn/news/view.asp?id397 &#xff08;3&#xff09;纸张设置&#xff1a; 1.打印机属性…

PPT缩印指南

PPT的讲义打印模式&#xff0c;虽然能把几张PPT打印在1页。但其实是个中看不中用的功能&#xff0c;因为各个页面间的间隔是无法消除的。为此还纠结了很长时间。 其实甩开打印讲义的功能&#xff0c;用普通的缩印方式就可以实现无间隔的缩印输出。 据说有个fineprint的软件可…

UNIX网络编程卷一 学习笔记 第十七章 ioctl操作

ioctl函数传统上一直作为那些不适合归入现有已定义类别的特性的系统接口。POSIX正在通过创建特定的包装函数来代替ioctl函数的某些功能&#xff0c;以取而代之的是那些已被POSIX标准化的函数。例如&#xff0c;Unix终端接口传统上使用ioctl函数访问&#xff0c;而POSIX为终端创…

wps,word缩印怎么设置

目录 wps&#xff0c;word缩印怎么设置 宋体 字号5&#xff08;注意&#xff1a;非五号字&#xff09;字体缩放80&#xff05;&#xff0c;字体间距-2 分为4栏 wps&#xff0c;word缩印怎么设置 宋体 字号5&#xff08;注意&#xff1a;非五号字&#xff09;字体缩放80&am…

缩印技巧你知多少?缩印怎么设置?

当打印word文档或者Excel表格时&#xff0c;如果花费很多时间去编辑格式&#xff0c;又或者需要把内容尽可能花最少的纸张页数打印出来&#xff0c;那么&#xff0c;有什么办法可以快速打印出来呢&#xff1f;缩印就可以帮到忙&#xff0c;缩印怎么设置&#xff1f;小编整理了w…

手机常识汇总

目录 一、手机历史介绍 第一代模拟制式手机(1G) 什么是模拟网? 模拟网络与数字网络的区别 数字通信与模拟通信相比具有明显的优点: 第二代数字手机(2G) 什么是“GSM” 什么是 “CDMA”? GSM 数字机和模拟手机话音相比 什么是“GSM/CDMA 双模机”? 什么是“TDMA”…

chatgpt赋能python:Python中的绝对值函数

Python中的绝对值函数 在Python编程语言中&#xff0c;绝对值函数是一个非常重要和常用的函数。它可以帮助我们快速地计算一个数的绝对值&#xff0c;而不需要手动使用if语句来处理。在本文中&#xff0c;我们将介绍Python中的绝对值函数&#xff0c;并且讨论它的一些应用。 …

微信H5页面点击直接跳转app-微信开放标签

开发微信H5项目时&#xff0c;需要从h5直接跳转至app&#xff0c;绞尽脑汁调研一番后&#xff0c;发现微信开放标签能实现&#xff0c;but 环境配置和测试流程真的很复杂&#xff0c;真的配置四小时&#xff0c;开发仅需30分钟&#xff0c;经过不断踩坑终于上线&#xff0c;踩过…

微信浏览器跳转app解决方案

微信浏览器跳转app解决方案 新版本微信浏览器中&#xff0c;已禁用打开其他APP应用&#xff0c;只支持打开微信合作商 APP应用&#xff0c;所以无法通过微信浏览器直接唤醒其他APP应用。列举微信浏览器唤醒APP的2种解决方案&#xff1a; 方案一&#xff1a;通过Url 跳转到H5…

uniapp 微信授权,微信分享,微信支付,微信跳转app集成

更新提示 &#xff01;&#xff01;&#xff01;&#xff01; 更新提示 &#xff01;&#xff01;&#xff01;&#xff01; 更新提示 &#xff01;&#xff01;&#xff01;&#xff01; 在7.12号微信推出不能强制获取用户信息才能使用。再授权之前得明确告知用户。经过我的…

如何将两个微信小程序合并_微信小程序--如何在两个页面之间传值

先看一下本周的部分的设计图 在这里插入图片描述 在这里插入图片描述

注意力机制

注意力机制&#xff1a;我们会把我们的焦点聚焦在比较重要的事物上。 对于一个模型而言&#xff08;CNN、LSTM&#xff09;&#xff0c;很难决定什么是重要的&#xff0c;什么是不重要的&#xff0c;由此注意力机制诞生了。 对于一张热力图而言&#xff0c;我们不难发现人类的…

Python篇——数据结构与算法(第四部分:希尔排序及其讨论、计数排序、桶排序、基数排序)

1、希尔排序 希尔排序&#xff08;shell sort&#xff09;是一种分组插入排序算法首先取一个整数d1n/2&#xff0c;将元素分为d1个组&#xff0c;每组相邻两元素之间距离为d1&#xff0c;在各组内进行直接插入排序取第二个整数d2d1/2&#xff0c;重复上述分组排序过程&#xf…

手把手QQ机器人制作教程,根据官方接口进行开发,基于Python语言制作的详细教程(更新中)

第 1 课、注册 QQ 开放平台账户 QQ开放平台官方地址&#xff1a;https://q.qq.com/#/app/bot QQ开放平台包含&#xff1a;QQ机器人、QQ小程序、QQ小游戏&#xff0c;我们这边选择QQ机器人。 机器人类型&#xff1a;设置私域机器人或者公域机器人&#xff0c;当然公域机器人对…

【0基础QQ机器人开发】基于go-cqhttp的QQ机器人开发教程,仅供自学

文章目录 一、本文目的:二、实现历程:三、开发过程1.准备工作1.cq-http的下载地址:[Releases Mrs4s/go-cqhttp (github.com)](https://github.com/Mrs4s/go-cqhttp/releases)2.python环境的配置 2.程序配置3.python程序开发4.常用API拓展 API 及与 OneBot 标准有略微差异的 AP…

【最新】半小时教你制作出属于自己的QQ机器人【保姆级】

目录 前言QQ机器人功能展示一、安装nonebot2安装步骤建立一个新的机器人项目 二、安装go-cqhttp安装步骤修改配置 三、使用 前言 相信大家都有在QQ群见过QQ机器人&#xff0c;可以玩游戏、推送当日天气情况等。本文将基于nonebot2和go-cqhttp构建一个自定义的QQ机器人。 QQ机…

如何在linux上使用QQ(在终端上使用qq) mojo-qq

如何在linux终端上使用QQ 效果展示 介绍irc irc的历史非常悠久&#xff0c;那都是上个世界别人用来聊天的了&#xff0c;算是我接触到的最早的及时聊天 以下是来自google的简介 Internet Relay Chat (IRC) is an application layer protocol that facilitates communicatio…

QQ机器人

一、介绍 qqbot 是一个用 python 实现的、基于腾讯 SmartQQ 协议的 QQ 机器人&#xff0c;可运行在 Linux 、 Windows 和 Mac OSX 平台下。 本项目 github 地址&#xff1a; https://github.com/pandolia/qqbot 你可以通过扩展 qqbot 来实现&#xff1a; 监控、收集 QQ 消息自动…