新客网WWW.XKER.COM:致力做中国最专业的网络学院!
学院: 操作系统 - 网络应用 - 服务器 - 网络安全 - 工具软件 - 办公软件 - Web开发 - 数据库 - 网页设计 - 图形图像 - 媒体动画 - 硬件学堂 - 存储频道 - QQ专区
您的位置:首页 > 软件开发 > .Net开发 > Asp.net教程 > 正文:枚举打印机(winapi)

枚举打印机(winapi)

新客网 XKER.COM 2004-12-17 来源: 收藏本文
using System;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;

namespace Sample.GetPrinter
{
class App
{
static void Main(string[] args)
{
Console.WriteLine("请输入你想搜索类型的序号:");
Console.WriteLine("1. Default printer(only Win95,Win98,WinME)\n2. Enumerates the locally installed printers;\n3. Enumerates the list of printers to which the user has made previous connections;\n4. Enumerates the printer identified by Name.;\n5. Enumerates network printers and print servers in the computer's domain;\n6. Enumerates printers that have the shared attribute;\n7. Enumerates network printers in the computer's domain;\n======================================================================");

int pt =0;
try
{
pt=Int32.Parse(Console.ReadLine());
}
catch(Exception e)
{
Console.WriteLine("错误信息: {0}",e.Message);
return;
}

PRINTER_ENUM printerKind = GetPrinterConType(pt);

PrinterSearcher p = new PrinterSearcher();

PrinterSearcher.PrinterInfo[] printers = p.Search(printerKind);

foreach(PrinterSearcher.PrinterInfo pi in printers)
{
Console.WriteLine("=====================================\n打印机名: {0}\n描叙:: {1}\n注释: {2}\n=====================================\n",
pi.Name, pi.Description, pi.Comment);
}
}

static PRINTER_ENUM GetPrinterConType(int ins)
{
switch(ins)
{
case 1:
return PRINTER_ENUM.DEFAULT ;
case 2:
return PRINTER_ENUM.LOCAL;
case 3:
return PRINTER_ENUM.CONNECTIONS;
case 4:
return PRINTER_ENUM.NAME;
case 5:
return PRINTER_ENUM.REMOTE;
case 6:
return PRINTER_ENUM.SHARED;
case 7:
return PRINTER_ENUM.NETWORK;
default:
return PRINTER_ENUM.LOCAL ;
}
}
}


#region 打印机位置状态枚举 PRINTER_ENUM
public enum PRINTER_ENUM
{
DEFAULT = 0x01,
LOCAL = 0x02,
CONNECTIONS = 0x04,
NAME = 0x08,
REMOTE = 0x10,
SHARED = 0x20,
NETWORK = 0x40
}
#endregion

#region 异常派生 EnumPrinterException
[Serializable]
public class EnumPrinterException: ApplicationException
{
public EnumPrinterException() { }
public EnumPrinterException (string message): base(message) { }
public EnumPrinterException (string message, Exception inner):
base(message, inner) {}
protected EnumPrinterException (SerializationInfo info,
StreamingContext context) : base(info, context)
{ }
}
#endregion

//加上这个属性可以按导出到非托管对像的顺序排序
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class PRINTER_INFO_1
{
public int flags;
public IntPtr pDescription;
public IntPtr pName;
public IntPtr pComment;
}

public class PrinterSearcher
{
#region Search
public PrinterInfo[] Search(PRINTER_ENUM printerKind)
{
PrinterInfo[] pInfo = new PrinterInfo[0];

uint iNeeded = 0, iReturned = 0, iSize = 0;
IntPtr printers = IntPtr.Zero;


if (!EnumPrinters(printerKind, String.Empty, 1, printers, 0, ref iNeeded, ref iReturned) )
{
//返回由上一个非托管函数返回的错误代码,该函数是使用设置了 -
//DllImport属性中SetLastError=true 标志的平台调用来调用的

int err = Marshal.GetLastWin32Error();
if (err != Win32Error.ERROR_INSUFFICIENT_BUFFER)
ThrowEnumPrinterException();
}

iSize = iNeeded;

if (iNeeded != 0)
{
try
{
//使用AllocHGlobal分配非托管内块
printers = Marshal.AllocHGlobal(new IntPtr(iSize));

//如果调用不成功抛出异常
if (!EnumPrinters(printerKind, String.Empty,1,printers, iSize, ref iNeeded, ref iReturned) )
{
ThrowEnumPrinterException();
}
else
{
pInfo = GetPrinterInfoFromMemory(printers, iReturned);
}
}
finally
{
//释放分配的内存块
if (printers != IntPtr.Zero)
Marshal.FreeHGlobal(printers);
}
}
return pInfo;
}
#endregion

#region PrinterInfo
public struct PrinterInfo
{
public string Name;
public string Description;
public string Comment;
}


public sealed class Win32Error
{
private Win32Error() {}
public const int ERROR_INSUFFICIENT_BUFFER = 122;
}
#endregion

#region 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
);
#endregion

#region GetPrinterInfoFromMemory
private PrinterInfo[] GetPrinterInfoFromMemory(IntPtr prInfo, uint numPrinters)
{
PRINTER_INFO_1 pi = new PRINTER_INFO_1();

PrinterInfo[] pInfo = new PrinterInfo[numPrinters];

for(int i = 0; i < numPrinters; i++)
{
//把数据从非托管内存传送到到托管内存
Marshal.PtrToStructure(prInfo, pi);

pInfo[i].Name = Marshal.PtrToStringAuto(pi.pName);
pInfo[i].Description = Marshal.PtrToStringAuto(pi.pDescription);
pInfo[i].Comment = Marshal.PtrToStringAuto(pi.pComment);

prInfo = new IntPtr(prInfo.ToInt32() + Marshal.SizeOf(typeof(PRINTER_INFO_1)));
}
return pInfo;
}

private void ThrowEnumPrinterException()
{
throw new EnumPrinterException(string.Format("LastErrorCode: {0}",
Marshal.GetLastWin32Error()));
}
#endregion
}
}


收藏】 【评论】 【推荐】 【投稿】 【打印】 【关闭
发表评论
要记得去论坛讨论,点击注册新会员匿名评论
评论内容:不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
阅读排行
随机推荐
实用信息推荐