我有一个需要打印票证的应用程序。每张票必须是唯一的。该应用程序是Windows窗体,完全用c#编写。对于我们的应用,我们使用的是三星ML-2525激光单色打印机。
流程基本上如下,操作员选择产品/票证(这是唯一的),然后按下一个按钮,完成两件事:
出于某种原因,每隔一段时间,需要打印的图像不会发送到打印机。这是一种罕见的情况,但它确实发生了。
我尝试使用Win32_Printer(http://msdn.microsoft.com/en-us/library/Aa394363)连接到打印机,但我无法获得当前打印机的状态(在线,离线,低碳粉,卡纸等)。我只能检查打印机是否存在以及纸张尺寸是否正确安装。我尝试了类似以下的代码,但它不起作用
private string MonitorPrintJobWmi()
{
var jobMessage = String.Empty;
var scope = new ManagementScope(ManagementPath.DefaultPath);
scope.Connect();
var selectQuery = new SelectQuery { QueryString = @"select * from Win32_PrintJob" };
var objSearcher = new ManagementObjectSearcher(scope, selectQuery);
var objCollection = objSearcher.Get();
foreach (var job in objCollection)
{
if (job != null)
{
jobMessage += String.Format("{0} \r\n", job["Name"].ToString());
jobMessage += String.Format("{0} \r\n", job["JobId"].ToString());
_jobId = Convert.ToInt32(job["JobId"]);
jobMessage += String.Format("{0} \r\n", job["JobStatus"].ToString());
jobMessage += String.Format("{0} \r\n", job["Status"].ToString());
}
}
return jobMessage;
}
我试图获得打印机的API,但我无法掌握它。顺便说一句,打印机的软件确实在Windows工具栏中指出了不同的错误。
我的问题是,是否有人能够指导我如何连接打印机并检查打印是否成功。
此外,如果有人知道我可以完成此操作的其他特定打印机,即更改硬件,将会很有帮助。
谢谢,
答案 0 :(得分:5)
要获取本地计算机上的打印队列列表,请尝试使用PrintServer的GetPrintQueues方法。
一旦您拥有与相关打印机关联的PrintQueue对象的实例,您就可以使用它来访问打印机的状态(IsOffline,IsPaperOut等)。此外,您可以使用它来获取给定队列中的作业列表(GetPrintJobInfoCollection),然后这将允许您获取特定于作业的状态信息(IsInError,IsCompleted,IsBlocked等)。
希望这有帮助!
答案 1 :(得分:0)
尝试打印PrintDocument(System.Drawing.Printing)后,尝试检查printjobs的状态。
第一步:初始化printDocument。
第二步:从System.Drawing.Printing.PrinterSettings.InstalledPrinters.Cast<string>();
将其复制到printerDocument.PrinterSettings.PrinterName
中第三步:尝试打印和处理。
printerDocument.Print();
printerDocument.Dispose();
最后一步:在任务中运行检查(不要阻止UI线程)。
Task.Run(()=>{
if (!IsPrinterOk(printerDocument.PrinterSettings.PrinterName,checkTimeInMillisec))
{
// failed printing, do something...
}
});
以下是实施:
private bool IsPrinterOk(string name,int checkTimeInMillisec)
{
System.Collections.IList value = null;
do
{
//checkTimeInMillisec should be between 2000 and 5000
System.Threading.Thread.Sleep(checkTimeInMillisec);
// or use Timer with Threading.Monitor instead of thread sleep
using (System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_PrintJob WHERE Name like '%" + name + "%'"))
{
value = null;
if (searcher.Get().Count == 0) // Number of pending document.
return true; // return because we haven't got any pending document.
else
{
foreach (System.Management.ManagementObject printer in searcher.Get())
{
value = printer.Properties.Cast<System.Management.PropertyData>().Where(p => p.Name.Equals("Status")).Select(p => p.Value).ToList();
break;
}
}
}
}
while (value.Contains("Printing") || value.Contains("UNKNOWN") || value.Contains("OK"));
return value.Contains("Error") ? false : true;
}
祝你好运。