C#获取打印机状态+API函数详解.docx
- 文档编号:15368916
- 上传时间:2023-07-03
- 格式:DOCX
- 页数:16
- 大小:21.22KB
C#获取打印机状态+API函数详解.docx
《C#获取打印机状态+API函数详解.docx》由会员分享,可在线阅读,更多相关《C#获取打印机状态+API函数详解.docx(16页珍藏版)》请在冰点文库上搜索。
C#获取打印机状态+API函数详解
usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Windows.Forms;
usingSystem.Runtime.InteropServices;
usingSystem.Diagnostics;
usingSystem.Drawing.Printing;
namespacetestprinter2
{
publicpartialclassForm1:
Form
{
#region预定义类型
[FlagsAttribute]
publicenumPrinterEnumFlags
{
PRINTER_ENUM_DEFAULT=0x00000001,
PRINTER_ENUM_LOCAL=0x00000002,
PRINTER_ENUM_CONNECTIONS=0x00000004,
PRINTER_ENUM_FAVORITE=0x00000004,
PRINTER_ENUM_NAME=0x00000008,
PRINTER_ENUM_REMOTE=0x00000010,
PRINTER_ENUM_SHARED=0x00000020,
PRINTER_ENUM_NETWORK=0x00000040,
PRINTER_ENUM_EXPAND=0x00004000,
PRINTER_ENUM_CONTAINER=0x00008000,
PRINTER_ENUM_ICONMASK=0x00ff0000,
PRINTER_ENUM_ICON1=0x00010000,
PRINTER_ENUM_ICON2=0x00020000,
PRINTER_ENUM_ICON3=0x00040000,
PRINTER_ENUM_ICON4=0x00080000,
PRINTER_ENUM_ICON5=0x00100000,
PRINTER_ENUM_ICON6=0x00200000,
PRINTER_ENUM_ICON7=0x00400000,
PRINTER_ENUM_ICON8=0x00800000,
PRINTER_ENUM_HIDE=0x01000000
}
[StructLayout(LayoutKind.Sequential)]
publicstructPRINTER_INFO_2
{
[MarshalAs(UnmanagedType.LPTStr)]
publicstringpServerName;
[MarshalAs(UnmanagedType.LPTStr)]
publicstringpPrinterName;
[MarshalAs(UnmanagedType.LPTStr)]
publicstringpShareName;
[MarshalAs(UnmanagedType.LPTStr)]
publicstringpPortName;
[MarshalAs(UnmanagedType.LPTStr)]
publicstringpDriverName;
[MarshalAs(UnmanagedType.LPTStr)]
publicstringpComment;
[MarshalAs(UnmanagedType.LPTStr)]
publicstringpLocation;
publicIntPtrpDevMode;
[MarshalAs(UnmanagedType.LPTStr)]
publicstringpSepFile;
[MarshalAs(UnmanagedType.LPTStr)]
publicstringpPrintProcessor;
[MarshalAs(UnmanagedType.LPTStr)]
publicstringpDatatype;
[MarshalAs(UnmanagedType.LPTStr)]
publicstringpParameters;
publicIntPtrpSecurityDescriptor;
publicuintAttributes;
publicuintPriority;
publicuintDefaultPriority;
publicuintStartTime;
publicuintUntilTime;
publicuintStatus;
publicuintcJobs;
publicuintAveragePPM;
}
#endregion
#region引用WindowsAPI
//引用API声明
[DllImport("winspool.drv",CharSet=CharSet.Auto,SetLastError=true)]
[return:
MarshalAs(UnmanagedType.Bool)]
publicstaticexternboolEnumPrinters(
PrinterEnumFlagsFlags,
stringName,
uintLevel,
IntPtrpPrinterEnum,
uintcbBuf,
refuintpcbNeeded,
refuintpcReturned
);
#endregion
///
///遍历打印机
///
///
///
[DllImport("User32.dll")]
publicstaticexternintMessageBox(inth,stringm,stringc,inttype);
publicForm1()
{
InitializeComponent();
}
privatevoidbutton1_Click(objectsender,EventArgse)
{
PRINTER_INFO_2[]Info2=null;
uintcbNeeded=0;
uintcReturned=0;
boolret=EnumPrinters(PrinterEnumFlags.PRINTER_ENUM_LOCAL,null,2,IntPtr.Zero,0,refcbNeeded,refcReturned);
IntPtrpAddr=Marshal.AllocHGlobal((int)cbNeeded);
ret=EnumPrinters(PrinterEnumFlags.PRINTER_ENUM_LOCAL,null,2,pAddr,cbNeeded,refcbNeeded,refcReturned);
if(ret)
{
Info2=newPRINTER_INFO_2[cReturned];
intoffset=pAddr.ToInt32();
for(inti=0;i { Info2[i]=(PRINTER_INFO_2)Marshal.PtrToStructure(newIntPtr(offset),typeof(PRINTER_INFO_2)); offset+=Marshal.SizeOf(typeof(PRINTER_INFO_2)); this.listBox1.Items.Add("打印机"+Info2[i].pPrinterName+"驱动为: "+Info2[i].pDriverName); this.listBox1.Items.Add(""); } Marshal.FreeHGlobal(pAddr); } //inta=MessageBox(0,Info2[0].pDriverName,"有",0); } }//endform }//endnamespace EnumPrinters函数中文简介 BOOLEnumPrinters( DWORDFlags,//typesofprinterobjectstoenumerate LPTSTRName,//nameofprinterobject DWORDLevel,//specifiestypeofprinterinfostructure LPBYTEpPrinterEnum,//pointertobuffertoreceiveprinterinfostructures DWORDcbBuf,//size,inbytes,ofarray LPDWORDpcbNeeded,//pointertovariablewithno.ofbytescopied(orrequired) LPDWORDpcReturned//pointertovariablewithno.ofprinterinfo.structurescopied ); 这个API用于了解可用的打印机的信息 参数的意义是: Flags: 可以是PRINTER_ENUM_LOCAL,PRINTER_ENUM_NAME,PRINTER_ENUM_SHARED,PRINTER_ENUM_DEFAULT, PRINTER_ENUM_CONNECTIONS等或者某些合法的组合 Name: 与Flag相关的名字,例如,服务器名,域名等 Level: 您希望返回的结构类型,95可以用1,2,5,NT可以用1,2,4,5 分别代表 PRINTER_INFO_1, PRINTER_INFO_2, PRINTER_INFO_4, PRINTER_INFO_5 各个结构的不同点是返回信息的详尽程度或者用途不同 pPrinterEnum: 您提供的一个接受返回结果的缓冲区 cbBuf: 这个缓冲区的大小(inBytes) pcbNeeded: 您提供的空间,API调用返回时,将告诉您用了pPrinterEnum多少字节(成功时),或者需要多少字节(如果空间不够) pcReturned: 您提供的空间,API调用返回时,将告诉您到底返回了多少个level中要求的结构 EnumPrinters返回非零值表示调用成功. EnumPrinters EnumPrinters VB声明 DeclareFunctionEnumPrintersLib"winspool.drv"Alias"EnumPrintersA"(ByValflagsAsLong,ByValnameAsString,ByValLevelAsLong,pPrinterEnumAsByte,ByValcdBufAsLong,pcbNeededAsLong,pcReturnedAsLong)AsLong 说明 枚举系统中安装的打印机 返回值 Long,非零表示成功,零表示失败。 会设置GetLastError 参数表 参数类型及说明 flagsLong,一个或多个下述标志 PRINTER_ENUM_LOCAL枚举本地打印机(包括Windows95中的网络打印机)。 名字会被忽略 PRINTER_ENUM_NAME枚举由name参数指定的打印机。 其中的名字可以是一个供应商、域或服务器。 如name为NULL,则枚举出可用的打印机 PRINTER_ENUM_SHARE枚举共享打印机(必须同其他常数组合使用) PRINTER_ENUM_CONNECTIONS枚举网络连接列表中的打印机(即使目前没有连接——仅适用于NT) PRINTER_ENUM_NETWORK枚举通过网络连接的打印机。 级别(Level)必须为1。 仅适用于NT PRINTER_ENUM_REMOTE枚举通过网络连接的打印机和打印服务器。 级别必须为1。 仅适用于NT nameString,vbNullString表示枚举同本机连接的打印机。 否则由标志和级别决定 LevelLong,1,2,4或5(4仅适用于NT;5仅适用于Win95和NT4.0),指定欲枚举的结构的类型。 如果是1,则name参数由标志设置决定。 如果是2或5,那么name就代表欲对其打印机进行枚举的服务器的名字;或者为vbNullString。 如果是4,那么只有PRINTER_ENUM_LOCAL和PRINTER_ENUM_CONNECTIONS才有效。 名字必须是vbNullString pPrinterEnumByte,包含PRINTER_ENUM_x结构的缓冲区,其中的x代表级别(Level) cbBufLong,pPrinterEnum缓冲区中的字符数量 pcbNeededLong,指向一个Long型变量的指针,该变量用于保存请求的缓冲区长度,或者实际读入的字节数量 pcReturnedLong,载入缓冲区的结构数量(用于那些能返回多个结构的函数) 注解 第4和第5级将它们的结构建立在系统注册表的基础上,而且比第2级快得多。 后者要求每台打印机都处于打开状态 C#中Typeof是干什么的? 2011-10-2106: 39匿名|分类: 编程语言|浏览5704次 提问者采纳 2011-10-2107: 25 C#typeof()和GetType()区是什么? 1、typeof(x)中的x,必须是具体的类名、类型名称等,不可以是变量名称。 2、GetType()方法继承自Object,所以C#中任何对象都具有GetType()方法,它的作用和typeof()相同,返回Type类型的当前对象的类型。 比如有这样一个变量i: Int32i=newInt32(); i.GetType()返回值是Int32的类型,但是无法使用typeof(i),因为i是一个变量,如果要使用typeof(),则只能: typeof(Int32),返回的同样是Int32的类型。 C#中int和IntPtr相互转换 方法一、 int转IntPtr inti=12; IntPtrp=newIntPtr(i); IntPtr转int intmyi=(int)p; MessageBox.Show(myi.ToString()); 方法二、 int转IntPtr inti=12; IntPtrp=(IntPtr)i IntPtr转int intmyi=(int)p; MessageBox.Show(myi.ToString()); IntPtr问题 publicaaa(IntPtrmyPtr,intleft,inttop,intwidth,shortheight) 这里myPtr应该是对应到一块内存,你需要查看aaa函数是如何把myPtr转化成它内部要使用的结构体的(一般都是结构体,也可能是其它对象,比如数组)。 然后,你需要在你的托管代码中,定义该结构体,使用StructLayout特性,对结构体的字段使用MarshalAs特性,类似这样: [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi,Size=13)] publicstructA101220Output { [MarshalAs(UnmanagedType.ByValTStr,SizeConst=11)] publicstringTransactionAccountID; [MarshalAs(UnmanagedType.ByValTStr,SizeConst=2)] publicstringIsAuthenticated; } 然后在需要使用的地方,获取该结构体对象的IntPtr,如下: //创建托管对象 A101220Outputoutput=newA101220Output(); output.TransactionAccountID="11000000841"; output.IsAutienticated="false"; //分配非托管内存,并获取非托管内存地址起始位置指针 intsize=Marshal.SizeOf(output); IntPtrbuffer=Marshal.AllocHGlobal(size); try { //将托管对象拷贝到非托管内存 Marshal.StructureToPtr(output,buffer,false); //调用非托管方法 aaa.(buffer,0,0,640,480); } finaly { //释放非托管内存 Marshal.FreeHGlobal(buffer); } FreeandSusan [转]C#中的IntPtr类型 本文转自: 问: c#中无法将类型“int”隐式转换为“System.IntPtr” 这个是我引用了一个api函数时出现的问题,我在声明中把intptr换成了int还是不可以,这是为什么呢? 要如何处理呢? 答: 您好,C#中的IntPtr类型称为“平台特定的整数类型”,它们用于本机资源,如窗口句柄。 资源的大小取决于使用的硬件和操作系统,但其大小总是足以包含系统的指针(因此也可以包含资源的名称)。 所以,在您调用的API函数中一定有类似窗体句柄这样的参数,那么当您声明这个函数时,您应该将它显式地声明为IntPtr类型。 例如,在一个C#程序中调用Win32APImciSendString函数控制光盘驱动器,这个函数的函数原型是: MCIERRORmciSendString( LPCTSTRlpszCommand, LPTSTRlpszReturnString, UINTcchReturn, HANDLEhwndCallback ); 首先在C#中声明这个函数: [DllImport("winmm.dll")] privatestaticexternlongmciSendString(stringa,stringb,uintc,IntPtrd); 然后用这样的方法调用: mciSendString("setcdaudiodooropen",null,0,this.Handle); 您也可以使用IntPtr.Zero将句柄设置为0; 或者使用类型强制转换: mciSendString("setcdaudiodooropen",null,0,(IntPtr)0); 或者,使用IntPtr构造函数: IntPtra=newIntPtr(2121); 这里有两点比较重要: 一是在C#中声明Win32API时,一定要按照WinAPI的原型来声明,不要改变它的数据类型; 二是尽量不要过多使用类型强制转换或构造函数的方式初始化一个IntPtr类型的变量,这样会使程序变得难于理解并容易出错 Marshal.SizeOf和sizeof的区别 sizeof在非Unsafe环境下只能用于预定义的一系列类型,如Int,Short等等。 而在Unsafe环境下,sizeof可以被用于值类型,但是值类型中不可以有引用类型,否则C#编译器会报错: errorCS0208: Cannottaketheaddressof,getthesizeof,ordeclareapointertoamanagedtype('SizeOf.Program.MyStruct') 而Marshal.SizeOf则是获得该类型被Marshal(转换,通常翻译为列集,指数据从一种类型转换到另外一种类型)到对应的非托管类型的大小。 和sizeof不同,Marshal.SizeOf允许用在含有引用类型的值类型上: 1: [StructLayout(LayoutKind.Sequential)] 2: structMyStruct 3: { 4: strings; 5: } Marshal.SizeOf(MyStruct)结果为4或者8,因为string被Marshal成char*。 如果用在不含有引用类型的值类型上,其结果也有可能和sizeof完全不一样,如对于下面的值类型: 1: structMyStruct 2: { 3: charb; 4: } sizeof(MyStruct)为2,而Marshal.SizeOf(typeof(MyStruct))结果则为1。 这是因为在.NET中char总是Unicode,而缺省情况下char会被Marshal成8位的Ansi字符,因此结果不同。 反之,如果我们指定这个char被Marshal成short值(也就是UTF16),如下: 1: [StructLayout(LayoutKind.Sequential)] 2: structMyStruct 3: { 4: [MarshalAs(UnmanagedType.I2)] 5: charb; 6: } 那么sizeof和Marshal.SizeOf结果均为2。 MarshalAs这个Attribute可以影响Marshal.SizeOf的结果,而不能影响sizeof的结果。 一个有意思的情况是,如果值类型不含任何成员,如下: 1: structMyStruct 2: { 3: } Sizeof和Marshal.SizeOf结果均为1,而不是0。 这个结果和C++的结果是一致的。 原因很简单: 如果声明一个这样的数组,如果元素大小为0的话,那么每个元素都具有相同的地址,这是不为C++标准所允许的,和正常的非0的情况也不一致。 .NET在这里采用和c++相同的规则,也认为空的值类型大小为1。 最后需要注意的
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C# 获取 打印机 状态 API 函数 详解
![提示](https://static.bingdoc.com/images/bang_tan.gif)