1

I am trying to send raw bytes to a printer. I have tried various printers and nothing seems to work. OpenPrinter returns a valid handle and both StartDocPrinter and StartPagePrinter succeed. Even WritePrinter succeeds and writer as many bytes as there was passed in and a print job appears in the spooler window. All appears like a success and still nothing gets printed.

I know writing raw bytes to printer is really printer-specific so I have tried printing to a file and sending those file's contents to WritePrinter. All appears fine and still no printout. What could be wrong? All sample code I have found so far does this 100% the same as I did. Here is the code:

if (OpenPrinter(printerName, &printer, NULL))
{
    DOC_INFO_1 docInfo = {L"Print Job", NULL, L"RAW"};

    DWORD printJob = StartDocPrinter(printer, 1, (LPBYTE) &docInfo);

    if (printJob != 0)
    {
        if (StartPagePrinter(printer))
        {
            DWORD written = 0;

            if (WritePrinter(printer, (LPVOID) (LPCSTR) str, str.GetLength(), &written))
            {
            }

            EndPagePrinter(printer);
        }

        EndDocPrinter(printer);
    }

    ClosePrinter(printer);
}

[Edit] Printer: Canon iP4200

wpfwannabe
  • 14,587
  • 16
  • 78
  • 129
  • Nothing obviously wrong with the code. Not documenting the printer make and model is a mistake. – Hans Passant Jan 30 '12 at 18:56
  • Edited question. Printer is Canon iP4200. Why vote to close already? – wpfwannabe Jan 30 '12 at 19:04
  • That's a cheap ink-jet printer, it only costs 9 dollars :) Not the kind of budget that allows a manufacturer to put a controller in the printer itself. – Hans Passant Jan 30 '12 at 19:13
  • Hm... pardon my ignorance, but this helps me how exactly? I suppose cheap printers are not worthy of an answer. Now seriously... so what if the printer has no "controller"? Why does that prevent me to send raw data to it? I am sure a printer driver sends something, why can't I? – wpfwannabe Jan 30 '12 at 19:20
  • 1
    You need to pass the printer specific configuration information completely in `str` in a language understood by the printer...likely not easily done with such a cheap printer. – user7116 Jan 30 '12 at 19:34
  • @sixlettervariables - Thanks! Do you know why sending the entire file previously generated by print-to-file for this specific printer would not work? This seems like exactly the RAW input the printer would expect, isn't it? – wpfwannabe Jan 30 '12 at 19:42
  • You're sending the data as if it was in the RAW format, however, what format was generated by print-to-file? PS? PCL? Some Windows specific format? "In Windows, the default format when you print to file is `.prn`." – user7116 Jan 30 '12 at 19:43
  • @sixlettervariables, all that changes when you select "print to file" is the destination for the bits. It still goes through the print driver to get translated properly. – Mark Ransom Jan 30 '12 at 19:51
  • @MarkRansom: then RAW may be appropriate, but I wonder if `"PRN"` as the format would work. I can recall using `"text"` with some dot matrix printers years ago. One other possibility is `str.GetLength()` is skipping nul characters. – user7116 Jan 30 '12 at 19:59
  • @sixlettervariables - str.GetLength() can be safely ignored. That's just one way I tried to implement it. I have other versions of code sending proper byte arrays, not strings. – wpfwannabe Jan 30 '12 at 20:02
  • @sixlettervariables: `PRN` does not work as "doc type" - just tried it - if that's what you meant. – wpfwannabe Jan 30 '12 at 20:04
  • 1
    @sixlettervariables: PRN isn't a valid data type unless the printer has its own print processor that supports it. Examples of standard Windows data types would be RAW, TEXT, NT EMF 1.003, and so forth. .prn is simply the default file extension for print-to-file. It is not a data type. – Carey Gregory Jan 30 '12 at 22:01
  • @CareyGregory: it was a SWAG. I guess the question remains, what is the data type of the prn output for his printer... – user7116 Jan 30 '12 at 22:08
  • @sixlettervariables: I couldn't say without being able to examine the printer properties. It's a cheap printer but it's also a photo printer, so it likely has its own print processor and custom data type. – Carey Gregory Jan 30 '12 at 22:14
  • 1
    @wpfwannabe: Go to printer properties, advanced tab, print processor. See what the data type is set to. Set yours to match in the docInfo struct. – Carey Gregory Jan 30 '12 at 22:16
  • @CareyGregory: Just been there and I get `Print processor dialog cannot be displayed.`. Still, I am not strictly looking for a specific solution for my particular printer but rather a generic one. How would I go about and do all of this programmatically? When I enumerate printers using `EnumeratePrinters` and `PRINTER_INFO_2` I get `RAW` for `pDatatype` for this printer. – wpfwannabe Jan 31 '12 at 07:18
  • Well, the results from EnumeratePrinters should be good enough, but something's seriously wrong with that printer or the machine if it can't display that dialog. Your solution looks sound to me in a generic sense. I would try it with another printer. You don't have to actually have the printer. Just install an HP LaserJet or something like that and set the port to FILE: or NUL: – Carey Gregory Jan 31 '12 at 15:54

0 Answers0