在我的应用程序(Windows 7,VS2010)中,我必须在成功打印图像后减少信用计数器。 无论如何,在开始整个过程之前,我想了解打印机状态,以便在纸张,卡纸等方面提醒用户。 现在,环顾四周我发现了几个使用Windows WMI的例子,但是......从来没有用过。例如,使用THIS代码段,如果我取出纸张,打开封面,打印机状态也随时可用。请关闭打印机。
现在打印机状态总是好的,我正在办公室测试在家里舒适地关闭的打印机。 我是否可以通过炸药引爆设备以获得打印机错误状态?
这是我用过的代码
ManagementObjectCollection MgmtCollection;
ManagementObjectSearcher MgmtSearcher;
//Perform the search for printers and return the listing as a collection
MgmtSearcher = new ManagementObjectSearcher("Select * from Win32_Printer");
MgmtCollection = MgmtSearcher.Get();
foreach (ManagementObject objWMI in MgmtCollection)
{
string name = objWMI["Name"].ToString().ToLower();
if (name.Equals(printerName.ToLower()))
{
int state = Int32.Parse(objWMI["ExtendedPrinterStatus"].ToString());
if ((state == 1) || //Other
(state == 2) || //Unknown
(state == 7) || //Offline
(state == 9) || //error
(state == 11) //Not Available
)
{
throw new ApplicationException("hope you are finally offline");
}
state = Int32.Parse(objWMI["DetectedErrorState"].ToString());
if (state != 2) //No error
{
throw new ApplicationException("hope you are finally offline");
}
}
}
收到'printerName'作为参数。
谢谢你的建议。
答案 0 :(得分:9)
你没有说你正在使用的是什么版本的.Net,但是从.Net 3.0开始就有了一些很好的打印功能。我用过这个,虽然我不能确定它报告各种状态级别,但我确实看到过各种打印机等“Toner Low”等消息。
PrinterDescription是一个自定义类,但您可以看到它使用的属性。
http://msdn.microsoft.com/en-us/library/system.printing.aspx
PrintQueueCollection printQueues = null;
List<PrinterDescription> printerDescriptions = null;
// Get a list of available printers.
this.printServer = new PrintServer();
printQueues = this.printServer.GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections });
printerDescriptions = new List<PrinterDescription>();
foreach (PrintQueue printQueue in printQueues)
{
// The OneNote printer driver causes crashes in 64bit OSes so for now just don't include it.
// Also redirected printer drivers cause crashes for some printers. Another WPF issue that cannot be worked around.
if (printQueue.Name.ToUpperInvariant().Contains("ONENOTE") || printQueue.Name.ToUpperInvariant().Contains("REDIRECTED"))
{
continue;
}
string status = printQueue.QueueStatus.ToString();
try
{
PrinterDescription printerDescription = new PrinterDescription()
{
Name = printQueue.Name,
FullName = printQueue.FullName,
Status = status == Strings.Printing_PrinterStatus_NoneTxt ? Strings.Printing_PrinterStatus_ReadyTxt : status,
ClientPrintSchemaVersion = printQueue.ClientPrintSchemaVersion,
DefaultPrintTicket = printQueue.DefaultPrintTicket,
PrintCapabilities = printQueue.GetPrintCapabilities(),
PrintQueue = printQueue
};
printerDescriptions.Add(printerDescription);
}
catch (PrintQueueException ex)
{
// ... Logging removed
}
}
答案 1 :(得分:7)
PrintQueue命名空间中的System.Printing类就是你所追求的。它具有许多属性,可提供有关其所代表的打印机状态的有用信息。以下是一些例子;
var server = new LocalPrintServer();
PrintQueue queue = server.DefaultPrintQueue;
//various properties of printQueue
var isOffLine = queue.IsOffline;
var isPaperJam = queue.IsPaperJammed;
var requiresUser = queue.NeedUserIntervention;
var hasPaperProblem = queue.HasPaperProblem;
var isBusy = queue.IsBusy;
这绝不是一个全面的列表,请记住,队列中可能有一个或多个这些状态,因此您必须考虑处理它们的顺序。
答案 2 :(得分:0)
所有品牌的打印机唯一可靠的解决方案是使用SNMP查询打印的页数,并确保它与发送的文档中的页数相匹配。
页面计数的SNMP OID为1.3.6.1.2.1.43.10.2.1.4
根据我的测试,其他每个策略都有不可靠的行为(重复获取打印队列时出现奇数空引用异常)或提供不准确的状态代码或页数。
答案 3 :(得分:0)
您可以按照上面指出的@mark_h使用打印机队列进行此操作。
但是,如果您的打印机不是默认打印机,则需要加载该打印机的队列。您需要执行的操作而不是调用server.DefaultPrintQueue
,而是需要通过调用GetPrintQueue()
加载正确的队列,然后向其传递打印机名称和空字符串数组。
//Get local print server
var server = new LocalPrintServer();
//Load queue for correct printer
PrintQueue queue = server.GetPrintQueue(PrinterName, new string[0] { });
//Check some properties of printQueue
bool isInError = queue.IsInError;
bool isOutOfPaper = queue.IsOutOfPaper;
bool isOffline = queue.IsOffline;
bool isBusy = queue.IsBusy;