使用ReadPrinter Winspool.drv成功从打印机读取数据

时间:2014-09-05 22:24:52

标签: c# printing

将原始命令发送到启用FGL的Practical Automation ITX3002票证打印机时,我遇到了一些问题。我一整天都在搜索,但是我找不到使用winspool.drv Windows库中的ReadPrinter方法的工作示例。

我发现的大多数代码示例都与网络打印机有关。这是一个通过USB连接的简单打印机。我需要检索一些我已经知道的响应结构的命令(复合结构,由供应商记录)。

我能够发送FGL命令以成功打印普通票和诊断票。我的问题是从打印机读回数据。我已经阅读了http://msdn.microsoft.com/en-us/library/dd162895(v=vs.85).aspx和其他几个地方的Microsoft文档。该文档没有解释如何发送此方法正在读取的数据。

所以,我真的不知道是否必须使用我需要的命令调用WritePrinter,关闭句柄,然后调用ReadPrinter来检索数据,或者如果我必须在单个打印机句柄管理中执行所有操作(I意思是,打开,工作并关闭打印机手柄。)

供应商对我非常耐心,但是回复并没有给我任何帮助,如何得到这个。

这是我的代码:

    [DllImport("winspool.Drv", EntryPoint = "ReadPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern Boolean ReadPrinter(IntPtr hPrinter, StringBuilder data, Int32 cbBuf, out Int32 pNoBytesRead);


    public static Boolean ReadBytesFromPrinter(String szPrinterName, out String data)
    {
        Int32 dwError = 0, dwWritten = 0;
        IntPtr hPrinter = new IntPtr(0);
        DOCINFOA di = new DOCINFOA();
        Boolean bSuccess = false; // Assume failure unless you specifically succeed.
        data = null;

        di.pDocName = "SendBytesToPrinter";
        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))
                {
                    Int32 maxRead = 256;
                    StringBuilder sbData = new StringBuilder(maxRead);

                    //Read Data                
                    bSuccess = ReadPrinter(hPrinter, sbData, maxRead, out dwWritten);
                    data = sbData.ToString();

                    EndPagePrinter(hPrinter);                        

                    EndDocPrinter(hPrinter);

                    ClosePrinter(hPrinter);
                }

            }
        }
        // If you did not succeed, GetLastError may give more information
        // about why not.
        if (bSuccess == false)
        {
            dwError = Marshal.GetLastWin32Error();
            data = null;
        }

        return bSuccess;
    }

ReadPrinter始终返回“false”,对GetLastWin32Error的调用始终为零。换句话说,有一个错误,没有关于什么的线索,也没有回读数据。

我按照http://support.microsoft.com/kb/322091中的说明发送命令,并且按预期成功运行,带有打印命令和诊断票据打印。

有谁知道代码和打印机之间的正确握手?它应该如何编写命令,以及如何读取响应?对我来说,创建打印作业,打印文档和打印页面以检索数据是没有意义的(我已经尝试过,BTW)。我错过了什么吗?我做错了吗?

1 个答案:

答案 0 :(得分:1)

您是否在打印机属性对话框的端口选项卡中选中了Expiry?如果它显示为灰色,则需要找到支持双向通信的驱动程序。