1

RawPrinterHelperMicrosoft のクラスhttp://support.microsoft.com/kb/322091を使用して、C# コードから Zebra KR403 プリンターに印刷していますが、すべて正常に動作しています。

プリンターの紙詰まりや紙切れなどの状態を監視したい。プリンターに送信できるクエリ "~HQES" または "esc eng 6" を見つけました。これにより、必要なものがすべて返されます。問題は、このクエリをプリンターに送信して、プリンターが応答できるようにする方法がわからないことです。クラスのWritePrinterRawPrinterHelperbool または long 型のみを返すようです。

また、プリンターのWin32_printerを見つけるためにオブジェクトを使用してみました。PrinterStatus/PrinterState/Errors次の方法を使用します。

public static string PrinterStateCheck(string szPrinterName)
    {
        string query = string.Format("SELECT * from Win32_Printer WHERE Name LIKE '%{0}%'", szPrinterName);
        ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
        ManagementObjectCollection collection = searcher.Get();
        string errorName = "";
        foreach (ManagementObject printer in collection)
        {
            int state = Convert.ToInt32(printer["PrinterState"]);
            errorName = state.ToString();
        }
        return errorName;

この方法を利用して、PrinterStatePrinterStatus、および を取得しようとしましたDetectedErrorStateが、必要な情報が得られません。PrinterState常に a を返し1024PrinterStatus常に a を返し4、常に aDetectedErrorStateを返します2。適切な印刷時と紙詰まりまたはメディア切れイベントで数回の印刷でPrinterState返されましたが、現在はすべての呼び出しで返されます。010241024

また、ネットワーク上のプリンターを監視するための独自のソフトウェアを Zebra が作成したこともわかりました。問題は、プリンターがネットワーク上になく、USB 経由でクライアント コンピューターにのみ接続されていることです。また、各レシートの印刷前または印刷後にプリンターの状態を確認したいと考えています。

winspool.Drv生データをプリンターに送信し、プリンターからデータを受信するために使用できるものがあることを願っています。

現在、 のReadPrinter関数を使用していますwinspool.Drvが、関数が返さ0れています。これは、プリンターからの応答にアクセスできないことを意味します。これは通常、プリンタが双方向通信用に設定されていないことを意味しますが、双方向通信が設定されていることは確かです。プリンターのプロパティの「ポート」タブで、「双方向サポートを有効にする」チェックボックスがオンになっている。また、Zebra セットアップ ユーティリティは、プリンタに正しくクエリを実行し、ダイレクト コミュニケーション ウィンドウで応答を受け取ることができます。

アドバイスありがとうございます。

ジェレミー

4

2 に答える 2

1

私は非常に似たようなことをしましたが、.NET で印刷ジョブを監視する方法はほとんどないと言えます。

私は次のことをして、近づいてきました:

  1. .NET PrintQueue オブジェクトのステータスと WMI の両方を照会する「PrinterDiagnosticsFacade」を作成します。どちらも常に正確ではありません。両方のデータをマージして、プリンターの真のステータスを決定します。

  2. 印刷ジョブがキューに残るように、プリンターの設定を調整します。これにより、印刷スプール ジョブに対して WMI クエリを実行することで、印刷ジョブの状態を正確に読み取ることができます。(印刷ファイル名と照合できます)

それが、プリンターのステータスに近づく方法です。

コードを追加して、.NET 印刷キュー オブジェクトを使用してどのように処理するかを示します。

コードを開始する printqueue オブジェクトについては、 http://msdn.microsoft.com/en-us/library/system.printing.printqueue.aspxを参照してください

PrintQueue me = Queue; 
if (me != null)
{
    me.Refresh();
    //in this if else,
    //i purposefully put the ones that error out first
    //so that if multiple can be true at the same time
    //the errors will definitely take precedence
    if (me.HasPaperProblem)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Error, "Error: Has paper problem");
    }
    else if (me.IsDoorOpened)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Error, "Error: Door is open");
    }
    else if (me.IsManualFeedRequired)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Error, "Error: Printer needs manually fed");
    }
    else if (me.IsNotAvailable)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Error, "Error: Printer not available");
    }

    else if (me.IsOutOfMemory)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Error, "Error: Printer is out of memory");
    }
    else if (me.IsOutOfPaper)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Error, "Error: Printer is out of paper");
    }
    else if (me.IsOutputBinFull)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Error, "Error: Printer output bin is full");
    }
    else if (me.IsPaperJammed)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Error, "Error: Paper jam");
    }
    else if (me.IsOffline)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Offline, "Offline");
    }
    else if (me.IsBusy)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Busy, "Busy");
    }
    else if (me.IsInitializing)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Busy, "Initializing");
    }
    else if (me.IsIOActive)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Busy, "Sending and recieving data");
    }
    else if (me.IsProcessing)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Busy, "Processing");
    }
    else if (me.IsWarmingUp)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Busy, "Warming up");
    }
    else if (me.IsPendingDeletion)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Busy, "Deleting a job");
    }
    else if (me.IsPaused)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Paused, "Paused");
    }
    else if (me.IsPrinting)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Printing, "Printing");
    }
    else if (me.IsPowerSaveOn)
    {
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Ready, "In power save mode");
    }
    else
        _SystemDotPrintingStatus = new PrinterStatus(PrinterStatusType.Ready, "Ready");
}
于 2011-12-08T17:13:05.937 に答える
1

WinUSB最終的に利用することになった問題の解決策は、プリンターのドライバーを作成することでした。このように、デバイスは USB デバイスとして扱われます。ZebraUSBドライバーを使用してオブジェクトが作成され、呼び出されたメソッドがWriteRead作成されました。WriteReadメソッドを使用して、~HQESクエリをプリンターに送信し、応答を受け取りました。クエリと応答の間にタイムラグがある場合があります。これに対抗するために、応答を変数に設定し、別の方法を使用して取得します。

私はWinUSBドライバーをコーディングしていないため、コードの詳細はわかりません。また、そのコードにアクセスすることもできません。

この回答の主なポイントはWinUSB、ステータス クエリが機能する前に、プリンターのドライバーを作成する必要があるということです。

于 2012-02-01T16:45:02.320 に答える