2012-08-02 8 views
14

私はチケットを印刷する必要があるアプリケーションを持っています。各チケットは一意でなければなりません。アプリケーションはWindowsフォームであり、完全にC#で書かれています。私たちのアプリケーションでは、Samsung ML-2525レーザー単色プリンタを使用しています。印刷プロセスが成功したかどうかを確認する方法はありますか?

流れは基本的に以下であり、オペレータが(一意である)製品/チケットをピックアップし、それは2つのことを行い、ボタンを押下する:使用される

  1. は、データベースに接続し、製品を更新します
  2. 何らかの理由でチケット(これはSystem.DrawingとGDI +を使用して行われる)

を印刷し、すべてのたまに、印刷される必要がある画像をプリンタに送信されません。まれなケースですが、それは起こります。

Win32_Printer(http://msdn.microsoft.com/en-us/library/Aa394363)を使用してプリンタに接続しようとしましたが、現在のプリンタの状態(オンライン、オフライン、トナー不足、紙詰まりなど)を取得できません。プリンタが存在し、用紙サイズが正しくインストールされているかどうかだけを確認できます。私は、次のようなコードを試してみましたが、それは、私は、プリンタのためのAPIを取得しようとしましたが、私はそれを手に入れることができませんでした

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; 
    } 

を動作しませんでした。ところで、プリンタのソフトウェアは、Windowsツールバーのさまざまなエラーを示しています。

私の質問は、プリンタに接続して印刷が成功したかどうかを誰かが正しい方向に導くことができるかどうかです。

また、誰かが私がこれを達成するかもしれない他の特定のプリンタ、つまりハードウェアを変更していることを知っていれば役に立ちます。

おかげで、

+0

関連項目:http://stackoverflow.com/questions/1921487/confirm-successful-print-programmatically-in-windows – Eugene

+0

私はそうしましたが、頭をはじめるためのサンプルコードが有益です。 – lopezbertoni

+2

@ lopezbertoni小さなグーグルでは、C#アプリケーションでこれらのリンクされたメソッドを使用する方法を紹介します。http://www.codeproject.com/Articles/51085/Monitor-jobs-in-a-printer-queue-NET –

答えて

5

のPrintServerのGetPrintQueues方法を試してみてください、ローカルマシン上のプリントキューのリストを取得します。

PrintQueueオブジェクトのインスタンスが関連するプリンタに関連付けられたら、それを使用してプリンタのステータス(IsOffline、IsPaperOutなど)にアクセスできます。また、特定のキュー(GetPrintJobInfoCollection)のジョブのリストを取得し、ジョブ固有のステータス情報(IsInError、IsCompleted、IsBlockedなど)を取得することもできます。

希望すると便利です。

+1

入力いただきありがとうございます。私があなたが言及したアプローチを使用してみましたが、私は成功しませんでした。主な問題は、ジョブがキューに到着してジョブが消え、プリンタが印刷ジョブを完了しないことです。 – lopezbertoni

+0

ジョブをプリンタに送信する前にキューの監視を開始すると、ジョブがキューに表示されるとすぐにジョブを捕まえることができるのでしょうか。 –

+0

これはなぜ答えとしてマークされていませんか?これは私をとても助けてくれました。私は特定のクライアント 'PrintQueue.Submitter'から送信されたジョブの数を調べることでこれを動作させることができました。そして、印刷を試みた後、新しく追加されたジョブのリストを取得し、 。このAPIを使用して、すべての単一ジョブまたはプリンタ自体のステータスを取得することもできます。仕事のIDとチケットの情報さえあります。 –

0

PrintDocument(System.Drawing.Printing)を印刷した後、printjobsのステータスを確認してみます。

最初の手順:printDocumentを初期化します。

第二ステップ:System.Drawing.Printing.PrinterSettings.InstalledPrinters.Cast<string>();

からお使いのプリンタ名を取得し、あなたのprinterDocument.PrinterSettings.PrinterNameに

第三ステップにそれをコピーします。印刷して処分してくださいを。

printerDocument.Print(); 
printerDocument.Dispose(); 

最後のステップ:タスクでチェックを実行します(UIスレッドをブロックしないでください)。

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;  
    } 

幸運:ここ

Task.Run(()=>{ 
    if (!IsPrinterOk(printerDocument.PrinterSettings.PrinterName,checkTimeInMillisec)) 
    { 
     // failed printing, do something... 
    } 
    }); 

は実装です。

関連する問題