首页学院源码字体下载软件电脑书| 素材图片模版壁纸酷站图标笔刷纹理|小游戏博客QQ表情投票计数器JoyRssMail
动态网站制作指南
首页|网络编程|站长之家|网页制作|图形图象|操作系统|冲浪宝典|软件教学|网络办公|手机学院|邮件系统|网络安全|认证考试
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > C#应用
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket

关于C#中枚举打印机


发表日期:2006-2-15 |


引言
前段时间为客户开发一套打印机配套的软件,对C#中调用打印机做了些研究。

---------------------------------------------

问题
.Net Framework 1.1给我们提供了一个PrinterSettings类,以提供指定有关文档打印方式的信息,其中包括打印文档的打印机。其中的静态属性InstalledPrinters可以使我们获取安装在计算机上所有打印机的名称。
但是可惜的是,该属性仅仅能够提供已安装的打印机的名称。对于获取该打印机的相关信息(如打印机类型等)却无能为力。问题就产生了,由于客户无法提供打印机的SDK,所以对打印机的筛选(处于商业目的,客户要求软件只能在使用他们的打印机时才能输出)只能通过打印机驱动的辨认来实现。

 

----------------------------------------------


解决方案一 使用WMI获取打印机信息

WMI,全称Windows Management Instrumentation。是可伸缩的系统管理结构,它采用一个统一的、基于标准的、可扩展的面向对象接口。WMI 为您提供与系统管理信息和基础 WMI API 交互的标准方法。WMI 主要由系统管理应用程序开发人员和管理员用来访问和操作系统管理信息。

.Net Framework中System.Management类提供了对WMI的支持,其中ManagementObjectSearcher用于根据指定的查询或枚举检索 ManagementObject 或 ManagementClass 对象的集合。

 /**//// <summary>
  /// Code 1:WMI搜索示例
  /// <summary>
  /// <param name="strDrivername">驱动名称</param>
  /// <returns>返回找到的打印机列表</returns>
  /// <remarks>strDrivername支持”%“以及”_“通配符查询,类似于SQL语句中的查询<remarks>
  public StringCollection GetPrintsWithDrivername( string strDrivername )
  {
   StringCollection scPrinters = new StringCollection();
   string strcheck = "";
   if( strDrivername !="" && strDrivername != "*" )
    strcheck = " where DriverName like \'" + strDrivername + "\'";
   string searchQuery = "SELECT Name FROM Win32_Printer" + strcheck;
   ManagementObjectSearcher searchPrinters =
    new ManagementObjectSearcher(searchQuery);
   ManagementObjectCollection printerCollection = searchPrinters.Get();
  
   foreach(ManagementObject printer in printerCollection)
   {
    string printname = printer.Properties["Name"].Value.ToString();
    scPrinters.Add(printname);
   }
   searchPrinters.Dispose();
   printerCollection.Dispose();

   return scPrinters;
  }


问题看上去基本解决了,运行程序的确是获得了正确的打印机列表。可是用户用了一段时间后发现,有的时候打印机无法正确获得,看来DOTNET调用WMI稳定性的确有点问题啊。。。。。。

WMI本身功能还是相当强大的,通过VBS基本可以涵盖WINDOWS最基本的操作。详细可以参加MSDN的文档。

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/wmi_start_page.asp

 

-------------------------------------------

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


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

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

关注此文的读者还看过:
·C#编写的windows计算器-源代码
·实用技巧:.Net框架类库中定时器类的使用
·C#获取mp3 Tag信息
·C#列出局域网中可用SQL Server服务器(续)
·存储过程中调用C#写的DLL
·C#用代码打开软键盘
·C#下从HTML文件生成DOM树
·在C#中编写多线程应用程序,简单!
·在CS类文件里向调用页面输出Javascript代码的3种方法
·如何创建和使用socket链接池

浏览全部C#的内容 PS笔刷下载 39种不同语言在线翻译
文章搜索服务





邮件订阅服务
输入你的邮件地址,你将不会错过任何关于<C#应用>的内容
Powered by JoyRssMail

网络编程文章分类

本月文章推荐
. 使用C#开发一个简单的P2P应用.
. 利用C#进行AutoCAD的二次开发(二).
. C# 制作出任意不规则按钮! (原理根.
. 如何用C#写所见即所得的设计器.
. 借用VB的My,C#照样条条大路通罗马.
. C#制作MID窗体.
. 使用C#与NNTP服务器交互!.
. 利用c#制作简单的留言板(4).
. c#数据结构之集合的实现(数组及链.
. VC# .Net中使用Crystal Report.
. 关于C#中枚举打印机.
. .NET中多线程的同步资源访问.
. C# winform treeview node添加右键.
. VS.Net C# 调用 Active 组件.
. C#加密路径里的参数,保护参数隐私安.
. 用CDO.Message打造邮件发送程序.
. C#画8位彩色图片(自定义调色板).
. 根据html页面模板动态生成html页面.
. 用 C# 开发 SQL Server 2005 的自定.
. 用C#实现生成PDF文档(附源码).
. c#DIY随机数类.
. C#中实现DataGrid双向排序.
. 利用C#实现标准的 Dispose模式.
. C#用代码打开软键盘.
. 如何用C#来部署数据库 .
. 序列化和反序列化XML应用程序设置类 .
. 用C#实现pdf文件的完整性验证.
. 在C#里使用using操作符.
. c# 实现Word联接Excel的MailMerge功.
. c#获取真实IP和代理IP.
  最新网站源码 最新软件下载
2009-7-4 84网址站 v4.10
2009-7-4 仿webmasterhome 网站收录查询 v
2009-7-4 NOCC v1.8
2009-7-4 易和阳光购物商城 v1.4 Access F
2009-7-4 OK伯乐招聘求职系统
2009-7-3 MyBB v1.4.8
2009-7-3 miniBB v2.3
2009-7-3 Modoer多功能点评系统 v1.1.0 Bu
2009-7-3 Modoer多功能点评系统 v1.1.0 Bu
2009-4-4 SharePoint Designer 2007
2009-3-20 Internet Explorer 8 简体中文正
2009-3-20 Internet Explorer 8 简体中文正
2009-3-20 Internet Explorer 8 简体中文正
2009-3-20 Internet Explorer 8 简体中文正
2009-3-20 Internet Explorer 8 简体中文正
2009-3-20 Internet Explorer 8 简体中文正
2009-3-20 Internet Explorer 8 简体中文正
2009-3-20 Internet Explorer 8 简体中文正
  发表评论
姓 名: 验证码: [ 查看评论 ]
内 容:
 
站长工具:Google PR查询|网站速度测试|CSS在线编辑器|OPEN参数生成器|弹出式窗口代码产生器|密码登录生成器|在线按钮生成器|Meta标签生成器|邮箱图标在线生成|多色彩特效字代码生成器|网页代码调试器|在线FTP登陆|Flash取色器|配色代码对照表|配色辞典|CSS生成器|CSS在线压缩|广告代码|框架网页代码生成器|js/vbs加密|md5加密|进制转换|UTF-8 转换工具|在线调色板|Html转换js|Html转换asp|Html转换php|Html转换perl
实用工具:汉字翻译拼音|拼音字典|在线翻译|天气预报|火星文|在线网速测试|符号对照表|个税计算|公积金贷款计算|购房银行按揭利率计算|实时汇率查询换算|经典小工具|汉字简繁转换|普通单位换算|公制单位换算|生辰老黄历|国内电话区号|国家代码与域名缩写|文字加密解密|元素周期表|健康查询|世界时间|全国各地车牌查询|全国车辆交通违章查询|万年历|二十四节气|汉字横竖排版|手机号码查询|计算器|ip搜索
广告刊登 | 版权声明 | 联系我们 | 加入收藏 | RSS订阅
Copyright © 2000-2009 www.knowsky.com All rights reserved | 沪ICP备05001343号