博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【转载】使用WIN32API获取打印机
阅读量:5989 次
发布时间:2019-06-20

本文共 1988 字,大约阅读时间需要 6 分钟。

使用WIN32API获取打印机

转来转去,又回到WIN32API上来了,无奈啊。。。。。。怪不得C++依然这么吃香 啊。。。。。

.Net给我们提供了DllImport来操作非托管的DLL(发现C#如此的强啊~~~~暗自偷笑)。

主要使用到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#中对非托管函数的调用,以及相互之间的数据封装还是一个比较难的地方,有空还需要整理一下。

转载于:https://www.cnblogs.com/fx2008/archive/2011/11/08/2240911.html

你可能感兴趣的文章
我的友情链接
查看>>
网络设备热备部署的三种模式
查看>>
前端性能优化
查看>>
redis主从复制机制讲解
查看>>
我的友情链接
查看>>
JAVA文件加密解密
查看>>
关于jQuery延时绑定
查看>>
C++编程 使用QT5 SDK录制屏幕并显示
查看>>
linux下防火墙iptables用法规则详解
查看>>
Java中equals和==的区别
查看>>
mysql@5.7 去掉严格模式
查看>>
浅谈百度是如何将关键词进行排序的
查看>>
Auditing with Hibernate Envers
查看>>
利用excel生成sql插入语句
查看>>
Delphi 与 DirectX 之 DelphiX(11): TPictureCollectionItem.DrawAdd、DrawSub
查看>>
ActiveMQ(07):ActiveMQ结合Spring开发--建议
查看>>
数据库设计范式的理解
查看>>
Delphi 中的 XMLDocument 类详解(21) - 暂停
查看>>
UIScrollView内容偏移的问题
查看>>
微信小程序教学第二章:小程序中级实战教程之预备篇 - 项目结构设计 |基于最新版1.0开发者工具...
查看>>