C# 使用WIN32API获取打印机

打印

主要使用到winspool.drv中的EnumPrinters函数,代码如下:

[DllImport("winspool.drv", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumPrinters ([MarshalAs(UnmanagedType.U4)] PRINTER_ENUM flags,
[MarshalAs(UnmanagedType.LPStr)] string sName,
uint iLevel,
IntPtr pPrinterDesc,
uint iSize,
[MarshalAs(UnmanagedType.U4)] ref uint iNeeded,
[MarshalAs(UnmanagedType.U4)] ref uint iReturned
);

说明:Marshal属性提供了对托管代码与非托管代码见数据封送。

EnumPrinters 的 WIN32 API的定义如下:

BOOL EnumPrinters(
DWORD Flags, // printer object types
LPTSTR Name, // name of printer object
DWORD Level, // information level
LPBYTE pPrinterEnum, // printer information buffer
DWORD cbBuf, // size of printer information buffer
LPDWORD pcbNeeded, // bytes received or required
LPDWORD pcReturned // number of printers enumerated
);

问题又来啦,EnumPrinters通过Level来获取PRINTER_INFO,而能获得打印机驱动的是PRINTER_INFO_2,而C#中又没有PRINTER_INFO_2结构,偶又开始晕了。。。。。

查了半天资料,网上基本上都是PRINTER_INFO_1的定义,而PRINTER_INFO_2不同与PRINTER_INFO_1,其中还包括DEVMODE结构,非托管的结构套结构,偶开始飘了~~~~

最后发现与其在C#中定义结构来对应非托管的结构,还不如直接用类来替代。所以定义了两个类

PRINTER_INFO_2以及DEVMODE(注:由于PRINTER_INFO_2中只用到了DEVMODE结构来接收打印机驱动的信息,所以只定义了这个类,对于其他类都没有做具体实现)。

在PRINTER_INFO_2中,对于所有的DWORD类型数据,全部对应到Int32类型上面,而对于所有LPTSTR、LPDEVMODE以及PSECURITY_DESCRIPTOR一律对应到IntPtr指针类型。

为了获取非托管中的数据,使用了一下函数获取打印机信息

.

PRINTER_INFO_2 pi = new PRINTER_INFO_2();
//把数据从非托管内存传送到到托管内存

for(int i = 0; i < numPrinters; i++)
{
Marshal.PtrToStructure( prInfo, pi ); //prInfo是由上面EnumPrinters获得的打印机

string driver = Marshal.PtrToStringAuto( pi.pDriverName );

if ( printerdriver == "" driver.ToLower().IndexOf( printerdriver ) != -1)
{

// 做相关处理

}
prInfo = new IntPtr(prInfo.ToInt32() + Marshal.SizeOf(typeof(PRINTER_INFO_2))); // 获取下一个打印机信息段开始
}
.

问题至此基本解决。但C#中对非托管函数的调用,以及相互之间的数据封装还是一个比较难的地方,有空还需要整理一下。

文章来源:http://spaces.msn.com/sharkoo/Blog/cns!D8E832CE4545AF!158.entry

补充:在2.0中,fixed关键字可以用于定义一个固定大小的数组缓存,而不是像1.x中那样还需要定义一个数字大小。但这种方式只能用于结构(struct)而不能用于类(class)的定义

 

时间: 2024-08-31 17:05:14

C# 使用WIN32API获取打印机的相关文章

获取打印机正在打印的数据

问题描述 获取打印机正在打印的数据 现在有一个需求,我的想法是写一个程序,一直监听打印机,如果有打印数据,先获取需要打印的数据,进行一定的加工然后再放回打印机继续打印.我现在只有这个想法但是不知道如何实现,请大神们提供一点思路,不限语言,越方便越好 解决方案 我也想要这答案,期待求解

怎吗获取打印机的句柄,来获取当前的打印进度,在打印完成的时候弹出对话框

问题描述 怎吗获取打印机的句柄,来获取当前的打印进度,在打印完成的时候弹出对话框 用什么函数可以获得打印机的句柄,有哪些参数.怎吗用这个句柄来获得当前打印的进度.

vb.net 获取打印机状态

问题描述 求助高手!1.获取电脑是否有联机打印机,并将联机打印机设置为默认打印机(状态为"就绪"的打印机).2.获取打印机状态,如果缺纸.缺墨.卡纸点.3.可以初始化打印机一些参数(打印机首选项) 解决方案 解决方案二:单纯的网页想获取本地一切硬件信息都是徒劳无功的...只能通过ocx....解决方案三:是应用程序,并非WEB程序.解决方案四:有人能帮我吗?解决方案五:获取打印机状态vb源码:不知你是否下载过,这个对USB打印机没有作用解决方案六:不止以上那些,还要看看各个类型的打印机

C# 获取打印机状态

问题描述 现在想做一个监控打印机状态的WPF用户控件.条形码打印机是斑马的ZDesignerGK888t(EPL).找了一天也没找到API.大家有什么方法得到打印机状态的没?或者有API的,求连接~. 解决方案 解决方案二:网上一大把解决方案三:引用楼主weichangqing00的回复: 现在想做一个监控打印机状态的WPF用户控件.条形码打印机是斑马的ZDesignerGK888t(EPL).找了一天也没找到API.大家有什么方法得到打印机状态的没?或者有API的,求连接~. 这里面的第二段,

C# 如何获取打印机出错状态

问题描述 C#获取打印机出错的信息,网上的什么泥人张,以及泥人张加强版的就不要复制粘贴了.来真火力的技术大牛 解决方案 解决方案二:C#获取的是打印机出错信息,比如缺纸缺墨这两个

.Net中获取打印机的相关信息

原文:.Net中获取打印机的相关信息 新项目中牵涉到对打印机的一些操作,最重要的莫过于获取打印机的状态,IP等信息,代码量不大,但是也是自己花了一点时间总结出来的,希望能帮助需要的朋友. PrinterCommunicate用于连接打印机并发送指令 1 public class PrinterCommunicate 2 { 3 4 public bool CheckNetWorkConnection(string strPrinterIP, int intPrinterPort) 5 { 6 S

C#遍历系统所安装的打印机,使用WMI方式获取打印机的所有属性

有网友发消息来询问,C#如何遍历系统已经安装的所有打印机,并获得每个打印机的相关信息,如:端口,名称等等 C#里面,虽然在 System.Drawing.Printing 这个namespace下,提供了一些对系统打印机的访问功能,但是,说实话是太弱了,对获取打印机的相关属性基本是无能为力的. C#里面获取打印机的详细信息,常用的用2种方式: 使用 Windows API 使用 WMI 我这里使用的是WMI的方式,因为此方式,是采用了类SQL的方法,将windows的WMI管理信息,作为一种数据

C# 获取打印机列表以及串口

C# 获取打印机列表以及默认打印机.串口列表.   /// <summary> /// 获取本地已安装的打印机 /// </summary> /// <returns></returns> public string GetPrinter() { string strList = ""; System.Drawing.Printing.PrinterSettings.StringCollection PrinterList = Syste

如何获取打印机参数

1.打印机的分辨率(象素/英寸) X方向分辨率=GetDeviceCaps(Printer->Handle,LOGPIXELSX): Y方向分辨率=GetDeviceCaps(Printer->Handle,LOGPIXELSY): 2.打印纸的大小(以象素为单位) 通过Printer的PageWidth和PageHeight属性可得到可打印范围的象素数 物理象素数用以下API得到: 宽=GetDeviceCaps(Printer->Handle,PHYSICALWIDTH) 高=Get