Description
Here I need to achieve a two way communication between Printer and app.
So far I'm able to write in the Printer using func writePrinter of winspool API. Issue that I am facing is for the readPrinter.
Code to open a Printer
final alloc = Arena();
final pPrinterName = printerName.toNativeUtf16(allocator: alloc);
final pWritePrinterHandle = alloc<HANDLE>();
final pDefault = alloc<PRINTER_DEFAULTS>()
..ref.pDatatype = nullptr
..ref.pDevMode = nullptr
..ref.DesiredAccess = PRINTER_ALL_ACCESS;
// Open Printer
var fSuccess = OpenPrinter(pPrinterName, pWritePrinterHandle, pDefault);
if (fSuccess == 0) {
final error = GetLastError();
throw Exception('OpenPrint error, status: $fSuccess, error: $error');
}
Code to send command to printer
final pDocInfo = alloc<DOC_INFO_1>()
..ref.pDocName =
'Boca Systems Communicator'.toNativeUtf16(allocator: alloc)
..ref.pDatatype =
'RAW'.toNativeUtf16(allocator: alloc) // RAW, TEXT or XPS_PASS
..ref.pOutputFile = nullptr;
//https://learn.microsoft.com/windows/win32/printdocs/startdocprinter
var fStartDocJobId =
StartDocPrinter(pWritePrinterHandle.value, 1, pDocInfo);
if (fSuccess == 0) {
final error = GetLastError();
throw Exception(
'StartDocPrinter error, status: $fSuccess, error: $error');
}
var fStartPrintSuccess = StartPagePrinter(pWritePrinterHandle.value);
// Print Row Data
String dataToPrint = '<S92>';
final cWritten = alloc<DWORD>();
final data = dataToPrint.toNativeUtf8(allocator: alloc);
final writeSuccess = WritePrinter(
pWritePrinterHandle.value, data, dataToPrint.length, cWritten);
if (dataToPrint.length != cWritten.value) {
final error = GetLastError();
throw Exception(
'WritePrinter error, status: $writeSuccess, error: $error');
}
Code to read Printer
final printerJobName = '$printerName, Job $fStartDocJobId';
final Completer<void> completer = Completer<void>();
final pReadPrinterHandle = alloc<HANDLE>();
final pReadDefault = alloc<PRINTER_DEFAULTS>()
..ref.pDatatype = nullptr
..ref.pDevMode = nullptr
..ref.DesiredAccess = PRINTER_USE_ACCESS;
final openPrinterDetailName = printerJobName.toNativeUtf16(allocator: alloc);
// Open Printer for Reading
var fReadOpenSuccess =
OpenPrinter(openPrinterDetailName, pReadPrinterHandle, pReadDefault);
if (fReadOpenSuccess == 0) {
final error = GetLastError();
throw Exception(
'Read OpenPrint error, status: $fReadOpenSuccess, error: $error, openPrinterDetailName $printerJobName');
}
final readBufferSize = 1024;
final pReadData = alloc<Uint8>(readBufferSize);
final bytesRead = alloc<Uint32>();
final readSuccess = ReadPrinter(
pReadPrinterHandle.value, pReadData, readBufferSize, bytesRead);
if (readSuccess == 0) {
final error = GetLastError();
throw Exception('ReadPrinter error, status: $readSuccess, error: $error');
}
// Process the read data
final readData = pReadData.cast<Utf8>().toDartString();
In the above code block the ReadPrinter is not getting executed as well no error is thrown.
// Open the printer for reading using the port name (e.g., "USB001, Port"), it is required to add the ", Port" keyword as a postfix.
int openReadPrinter() {
final Pointer<Utf16> pPortName = portName.toNativeUtf16();
final success = OpenPrinter(pPortName, readPrinterHandle, nullptr);
if (success == 0) {
final error = GetLastError();
throw Exception('OpenPrint Read error, status: $success, error: $error');
}
return success;
}
// Function to read from the printer
String readFromPrinter() {
const readBufferSize = 1024;
final pReadData = alloc<Uint8>(readBufferSize);
final bytesRead = alloc<Uint32>();
final success =
ReadPrinter(readPrinterHandle, pReadData, readBufferSize, bytesRead);
if (success == 0) {
final error = GetLastError();
throw Exception("Read from printer failed. Error: $error");
} else {
return pReadData.cast<Utf8>().toDartString();
}
}
In the above code:
openReadPrinter
function opens the printer for reading using the specified port name (portName). If successful, it returns a non-zero value; otherwise, it throws an exception with the error details.ReadPrinter
fails to read from the printer, providing information about the error encountered.This code demonstrates how to achieve two-way communication between your application and the printer in Dart using the winspool API.