Delphi: PJL commands to printer and reading the responses back

4.3k views Asked by At

Im struggling with getting information back from the printer when sending PJL to the printer. The printer supports PJL and it is a USB printer. Now getting information / examples seems to be a problem or I'm looking at the wrong places. I know on MSDN there are a lot of information, but I've tried everything I got there, from docinfo's to write/read printers and nothing seems to work.

Some people say you can use writeprinter and readprinter. I've tried this, when I writeprinter, the printer seems to "do" something, but readprinter returns or errors or blanks. Now I think this could be because the print driver is "locking" the port, so you cant read information back from it?

The other option I saw somewhere is to use writefile and readfile. Here you would get the physical port part for the printer, for example '\?\USB#VID_05CA&PID_0403#S5208603411#{28d78fad-5a12-11d1-ae5b-0000f803a8c2}'. Then you change the port to "FILE". Use the writefile and readfile with the path as the physical path from above. Get the information you need and then set the port back to the original port. Tried this as well, also getting errors.

Im just trying to do a simple @PJL INFO PAGECOUNT (I left out the escape chars etc, etc). The string is correct, because using the string on networked printers, its working 100% and I can get the information. But local printers is a problem.

Is there anyone that has this working or a working example? Any help would be much appreciated.

PS: Below is 1 of the 100's of examples I've tried. This is the writeprinter example:

procedure TForm1.Button5Click(Sender: TObject);
Const
    Defaults: TPrinterDefaults = (
      pDatatype : Nil;
      pDevMode  : nil;
      DesiredAccess :  PRINTER_ACCESS_USE or PRINTER_ACCESS_ADMINISTER  ) ;
Var
  Device : array[0..255] of char;
  FPrinterHandle:THandle;
  DocInfo1: TDocInfo1;
  Buffer, Buffer2:PChar;
  Written, Len:Cardinal;
  i: Integer;
  sPath: String;
Begin

  StrCopy(Device,PChar('RICOH Aficio SP 4210N PCL 6'));
  OpenPrinter(@Device, FPrinterHandle, @Defaults);

  DocInfo1.pDocName := 'test';
  DocInfo1.pOutputFile := Nil;
  DocInfo1.pDatatype := 'RAW';

  StartDocPrinter(FPrinterHandle, 1, @DocInfo1);

  StartPagePrinter(FPrinterHandle);

  Buffer := #27+'%-12345X@PJL COMMENT'+#13+#10+'@PJL INFO PAGECOUNT'+#13+#10+#27+'%-12345X';

  WritePrinter(FPrinterHandle,@Buffer,Length(Buffer), Written);

  EndPagePrinter(FPrinterHandle);

  EndDocPrinter(FPrinterHandle);

// everithing is OK here, BUT

  ReadPrinter(FPrinterHandle, @Buffer2, Length(Buffer2), len  );

end;
1

There are 1 answers

1
Alistair Ward On

Check http://www.undocprint.org/winspool/tips_and_tricks for an explanation of what to do, and some sample C code.

Even with this code the chances of this working for you are minimal. To be able to read back from the printer, the port monitor must support bidirectional mode, and the standard USB port monitor does not.

Also, in your code above, Buffer2 passed to ReadPrinter() is not correct. You need to pre-allocate buffer space, and then pass the address of the buffer, not the address of the pointer to the buffer...

var
    Buffer2 : array[0..255] of Char;
begin
...
ReadPrinter( FPrinterHandle, @Buffer2[0], Length(Buffer2), len );
end;