【转载】使用WIN32API获取打印机

使用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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值