1

Epson ESC/POS プロトコルや ZPL Zebra プロトコルなどのサーマル プリンターに印刷するアプリケーションを開発する必要があります。ネットワーク プリンタ、シリアル ポート プリンタ、およびウィンドウのスプーラ プリンタを使用して、未加工のコードをプリンタに書き込むことができます。問題は、プリンターのステータス (準備完了、エラー、用紙切れなど) を取得するためにプリンターに「クエリ」を実行する必要があるときに始まります。 . ネットワーク/ソケット プリンタまたはシリアル ポート プリンタでは、すべてが明確です... Windows プリンタでは、プリンタのステータスを読み取る方法がわかりません...

解決策はありますか?

アップデート

Hans の提案に従って、Windows API を使用してプリンターを読み取ろうとしています。これは、ESC/POS プロトコルを使用した私のテストです。

public class WinPrinter
{
    // Structure and API declarions:
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public class DOCINFOA
    {
        [MarshalAs(UnmanagedType.LPStr)]
        public string pDocName;
        [MarshalAs(UnmanagedType.LPStr)]
        public string pOutputFile;
        [MarshalAs(UnmanagedType.LPStr)]
        public string pDataType;
    }
    [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);

    [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool ClosePrinter(IntPtr hPrinter);

    [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);

    [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool EndDocPrinter(IntPtr hPrinter);

    [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool StartPagePrinter(IntPtr hPrinter);

    [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool EndPagePrinter(IntPtr hPrinter);

    [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);

    [DllImport("winspool.Drv", EntryPoint = "ReadPrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool ReadPrinter(IntPtr hPrinter, [MarshalAs(UnmanagedType.LPStr)] StringBuilder pBytes, Int32 dwCount, out Int32 dwNReadBytes); 

    public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
    {
        Int32 dwError = 0, dwWritten = 0;
        IntPtr hPrinter = new IntPtr(0);
        DOCINFOA di = new DOCINFOA();
        bool bSuccess = false; // Assume failure unless you specifically succeed.

        di.pDocName = "My C#.NET RAW Document";
        di.pDataType = "RAW";

        // Open the printer.
        if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
        {
            // Start a document.
            if (StartDocPrinter(hPrinter, 1, di))
            {
                // Start a page.
                if (StartPagePrinter(hPrinter))
                {
                    // Write your bytes.
                    bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
                    EndPagePrinter(hPrinter);
                }
                EndDocPrinter(hPrinter);
            }
            string reaDstrinG = "";
            Int32 buf = 0;
            Int32 pcRead;
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            bool read = ReadPrinter(hPrinter, sb.Append(reaDstrinG), buf, out pcRead);
            ClosePrinter(hPrinter);
        }
        // If you did not succeed, GetLastError may give more information
        // about why not.
        if (bSuccess == false)
        {
            dwError = Marshal.GetLastWin32Error();
        }
        return bSuccess;


      }

       static void Main(string[] args)
        {
            String test = "\u0010\u0004\u0001";
            IntPtr pBytes=Marshal.StringToCoTaskMemAnsi(test);
            Int32 dwCount = test.Length;
            WinPrinter.SendBytesToPrinter("BIXOLON SRP-350 (Copia 1)",pBytes,dwCount);
        }

    }

"\u0010\u0004\u0001" (DLE EOT 1) は、ESCPOS プロトコルでプリンター ステータスを要求するコマンドであると確信しています。シリアルで接続された同じプリンターでテストしたところ、ステータス バイトが得られました。

ただし、上記のコードでは、ReadPrinter メソッドから常に false になります。プリンターポートで「双方向」オプションが有効になっていることを確認し、スプーラーオプションなしでも試しました。

4

0 に答える 0