-1

I have Zebra printer connected via USB and I'm trying to read printer's memory using command ^XA^HWR:^XZ. The command works on TCP/IP.

I'm not even sure if I have method header right.

[DllImport("winspool.Drv", EntryPoint = "ReadPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
static extern bool ReadPrinter(IntPtr hPrinter, IntPtr pBuf, int cbBuf, out int pNoBytesRead);

Method ReadPrinter always returns false and 0 read bytes. When I'm trying to get LastWin32Error, I'm getting a variety of 0, 6 or 63 (ERROR_SUCCESS - although it returns false and no data, ERROR_INVALID_HANDLE or ERROR_PRINT_CANCELLED), depending on that I'm trying. I've tried several method headers and different approaches but none of them lead to the success data read. I have 'bidirectional support' enabled and printer drivers installed. It may seem as duplicates of other threads, but I've already got through them and none of them was helpful.

Code snippet:

    private static void SendBytesToPrinter(string printerName, IntPtr pointerBytes, int bytesCount)
    {
        int written = 0;
        PrintResult printResult = new PrintResult();
        IntPtr pointerPrinter = new IntPtr(0);
        DOCINFOA docInfo = new DOCINFOA();
        bool success = false;

        docInfo.DocName = "RAW Document";
        docInfo.DataType = "RAW";

        try
        {
            if (OpenPrinter(printerName.Normalize(), out pointerPrinter, IntPtr.Zero))
            {
                if (StartDocPrinter(pointerPrinter, 1, docInfo))
                {
                    if (StartPagePrinter(pointerPrinter))
                    {
                        success = WritePrinter(pointerPrinter, pointerBytes, bytesCount, out written);
                        EndPagePrinter(pointerPrinter);
                    }

                    EndDocPrinter(pointerPrinter);
                 }

                 // READ HERE
                 Int32 bufLen = 32;
                 IntPtr pStatus = Marshal.AllocCoTaskMem(bufLen);
                 Int32 statusLen = 0;
                 bool bSuccess = ReadPrinter(hPrintJob, pStatus, bufLen, out statusLen);

                 ClosePrinter(pointerPrinter);
             } 
        } catch (Exception ex) { }
    }
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Bukk94
  • 419
  • 1
  • 6
  • 23
  • There *is* [documentation](https://msdn.microsoft.com/en-us/library/windows/desktop/dd162895.aspx). – IInspectable Aug 06 '18 at 07:56
  • @IInspectable That doesn't help me at all. I've never worked with externs at a deep level, I have no idea what's `LPVOID` or `DWORD`. I saw this page before but it didn't make sense to me. I didn't find any working example. – Bukk94 Aug 06 '18 at 08:01
  • This article may be helpful. [Thread: RESOLVED VS2008 / VS 2012. Win 7. USB Printing to Zebra - Bidirectional Communications. USB004](http://www.vbforums.com/showthread.php?770307-RESOLVED-VS2008-VS-2012-Win-7-USB-Printing-to-Zebra-Bidirectional-Communications-USB004) VB sample code is attached. [USBZebra-BiDirectional.zip](http://www.vbforums.com/attachment.php?s=638723c4191a242d07d907f90766bac7&attachmentid=147053&d=1493209353) – kunif Aug 06 '18 at 08:09
  • Whether it helps you or not doesn't make a difference. There *is* documentation. Of course you need to know C to understand a C interface. Are you asking for basic P/Invoke help instead? – IInspectable Aug 06 '18 at 08:11
  • @IInspectable My apology then. I've managed to print using WritePrinter so I thought ReadPrinter would be similar. Apparently, I was wrong. I would like to know _why_ the ReadPrinter returns false/0 bytes. – Bukk94 Aug 06 '18 at 08:18

1 Answers1

0

I solved it by using Visual Basic example, using FileStreams and StreamReaders. Thanks to @kunif for pointing out the sample code.

kernel32.dll is way to go instead of winspool.Drv

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern SafeFileHandle CreateFile(string lpFileName, EFileAccess dwDesiredAccess, 
                                                EFileShare dwShareMode, IntPtr lpSecurityAttributes, 
                                                ECreationDisposition dwCreationDisposition, 
                                                EFileAttributes dwFlagsAndAttributes, 
                                                IntPtr hTemplateFile);

private static string ReadUsbPort(StreamReader sr)
{
    string readResult = string.Empty;
    if (sr != null && sr.BaseStream != null)
    {
       do
       {
            readResult += sr.ReadLine();
            readResult += "\r";
        }
        while (sr.EndOfStream == false);
     }
   return readResult;
}

Very useful is combination of GUID_DEVINTERFACE_USB_DEVICE and WinUSBNet

Bukk94
  • 419
  • 1
  • 6
  • 23