|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
实不相瞒,Java是我见过的执行效率最低的程序设计语言,前不久在CSDN论坛上有个评测,计算9999的阶乘,同样的循环算法,Java的耗时是.NET的5倍。打印弁言
前段工夫为客户开辟一套打印机配套的软件,对C#中挪用打印机做了些研讨。
---------------------------------------------
成绩
.NetFramework1.1给我们供应了一个PrinterSettings类,以供应指定有关文档打印体例的信息,个中包含打印文档的打印机。个中的静态属性InstalledPrinters可使我们猎取安装在盘算机上一切打印机的称号。
可是惋惜的是,该属性仅仅可以供应已安装的打印机的称号。关于猎取该打印机的相干信息(如打印机范例等)却力所不及。成绩就发生了,因为客户没法供应打印机的SDK,以是对打印机的选择(处于贸易目标,客户请求软件只能在利用他们的打印机时才干输入)只能经由过程打印机驱动的识别来完成。
----------------------------------------------
办理计划一利用WMI猎取打印机信息
WMI,全称WindowsManagementInstrumentation。是可伸缩的体系办理布局,它接纳一个一致的、基于尺度的、可扩大的面向工具接口。WMI为您供应与体系办理信息和基本WMIAPI交互的尺度办法。WMI次要由体系办理使用程序开辟职员和办理员用来会见和操纵体系办理信息。
.NetFramework中System.Management类供应了对WMI的撑持,个中ManagementObjectSearcher用于依据指定的查询或列举检索ManagementObject或ManagementClass工具的汇合。
/**////<summary>
///Code1:WMI搜刮示例
///<summary>
///<paramname="strDrivername">驱动称号</param>
///<returns>前往找到的打印机列表</returns>
///<remarks>strDrivername撑持”%“和”_“通配符查询,相似于SQL语句中的查询<remarks>
publicStringCollectionGetPrintsWithDrivername(stringstrDrivername)
{
StringCollectionscPrinters=newStringCollection();
stringstrcheck="";
if(strDrivername!=""&&strDrivername!="*")
strcheck="whereDriverNamelike"+strDrivername+"";
stringsearchQuery="SELECTNameFROMWin32_Printer"+strcheck;
ManagementObjectSearchersearchPrinters=
newManagementObjectSearcher(searchQuery);
ManagementObjectCollectionprinterCollection=searchPrinters.Get();
foreach(ManagementObjectprinterinprinterCollection)
{
stringprintname=printer.Properties["Name"].Value.ToString();
scPrinters.Add(printname);
}
searchPrinters.Dispose();
printerCollection.Dispose();
returnscPrinters;
}
成绩看上往基础办理了,运转程序切实其实是取得了准确的打印机列表。但是用户用了一段工夫后发明,有的时分打印机没法准确取得,看来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)]
privatestaticexternboolEnumPrinters([MarshalAs(UnmanagedType.U4)]PRINTER_ENUMflags,
[MarshalAs(UnmanagedType.LPStr)]stringsName,
uintiLevel,
IntPtrpPrinterDesc,
uintiSize,
[MarshalAs(UnmanagedType.U4)]refuintiNeeded,
[MarshalAs(UnmanagedType.U4)]refuintiReturned
);
申明:Marshal属性供应了对托管代码与非托管代码见数据封送。
EnumPrinters的WIN32API的界说以下:
BOOLEnumPrinters(
DWORDFlags,//printerobjecttypes
LPTSTRName,//nameofprinterobject
DWORDLevel,//informationlevel
LPBYTEpPrinterEnum,//printerinformationbuffer
DWORDcbBuf,//sizeofprinterinformationbuffer
LPDWORDpcbNeeded,//bytesreceivedorrequired
LPDWORDpcReturned//numberofprintersenumerated
);
成绩又来啦,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_2pi=newPRINTER_INFO_2();
//把数据从非托管内存传送到到托管内存
for(inti=0;i<numPrinters;i++)
{
Marshal.PtrToStructure(prInfo,pi);//prInfo是由下面EnumPrinters取得的打印机
stringdriver=Marshal.PtrToStringAuto(pi.pDriverName);
if(printerdriver==""||driver.ToLower().IndexOf(printerdriver)!=-1)
{
//做相干处置
}
prInfo=newIntPtr(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)的界说。
我实在想不明白java的机制,为什么非要那么蛋疼,在同一个平台下重复编译。 |
|