OPOS PosPrinter.PrintNormal not printing - c#

Below are my code:
PosExplorer posExplorer = new PosExplorer();
DeviceCollection receiptPrinterDevices = posExplorer.GetDevices(DeviceType.PosPrinter);
DeviceInfo receiptPrinterDevice = posExplorer.GetDevice(DeviceType.PosPrinter,"SRP2");
PosPrinter printer = (PosPrinter)posExplorer.CreateInstance(receiptPrinterDevice);
printer.Open();
printer.Claim(10000);
printer.DeviceEnabled = true;
printer.PrintNormal(PrinterStation.Receipt, "test print 1");
I debug and everything went through without exception, already confirmed also that the printer targeted is the correct one, however the printer is not printing anything. Is there any step that I did wrong? Any guidance is greatly appreciated. Thanks
If it helps, My Printer Interface via Ethernet to a specific IP.

The problem appears to be that you are not sending a new line character (\n) at the end of your PrintNormal string, without it the service object will just buffer the line data, waiting until it sees the \n before sending the data to the device.
printer.PrintNormal(PrinterStation.Receipt, "test print 1\n");
From the POS for .net Documentation on PrintNormal
Newline / Line Feed (10 Decimal)
Print any data in the line buffer, and feed to the next print line. (A carriage return is not required in order to print the line.)
This is because the printer must print one complete line at a time, so it waits until you tell it that you have completed a line before starting to print, this allows you to use 2 or more PrintNormal calls for a single line of printout to build up the line data if needed (e.g. in a loop).
I have ran the below code on a networked POS Printer (Tysso PRP-250) and with the \n it prints the line, without it it does not.
PosExplorer posExplorer = new PosExplorer();
DeviceInfo receiptPrinterDevice = posExplorer.GetDevice(DeviceType.PosPrinter, "SRP2");
PosPrinter printer = posExplorer.CreateInstance(receiptPrinterDevice) as PosPrinter;
printer.Open();
printer.Claim(10000);
if (printer.Claimed)
{
printer.DeviceEnabled = true;
printer.PrintNormal(PrinterStation.Receipt, "test print 1\n");
printer.DeviceEnabled = false;
}
printer.Release();
printer.Close();

Related

Setting PrinterSettings.PrinterName leads to printing of junk value on print of crystal report

I am trying to print a crystal report in WPF C# by sending it directly to printer without a viewer .The user can select different printers based on a drop down .However when i try to set PrinterSettings.PrinterName="PrinterName" ,the printer is printing junk values
My code is
ReportDocument ObjDoc = new ReportDocument();
System.Drawing.Printing.PrintDocument pDoc = new System.Drawing.Printing.PrintDocument();
CrystalDecisions.Shared.PrintLayoutSettings PrintLayout = new CrystalDecisions.Shared.PrintLayoutSettings();
System.Drawing.Printing.PrinterSettings printerSettings = new System.Drawing.Printing.PrinterSettings();
System.Drawing.Printing.PageSettings pSettings = new System.Drawing.Printing.PageSettings(printerSettings);
System.Drawing.Printing.PageSettings pageSettings = new System.Drawing.Printing.PageSettings(printerSettings);
//Fetch Values in dataset cdtUTDocEng
ObjDoc.Load("//ServerName//Crystal_Reports//VHRSSALEFDE002.rpt");
if (cdtUTDocEng.Rows.Count > 0)
ObjDoc.SetDataSource(cdtUTDocEng);
else
{
lsPrintMessage = "Printing Failed -Failed to fetch Undertaking English details";
break;
}
if (cEnvironment.Production == psEnvironment)
{
ObjDoc.PrintOptions.PrinterDuplex = PrinterDuplex.Default;
lsPrinterName = cmbPrinter.SelectedValue.ToString().Trim();
if (CheckifPrinterInstalled(cmbPrinter.SelectedValue.ToString().Trim()) == true)
{
System.Drawing.Printing.PrinterSettings.PrinterName =cmbPrinter.SelectedValue.ToString().Trim();
ObjDoc.PrintToPrinter(printerSettings, pSettings, false, PrintLayout);
ObjDoc.Dispose();
lsPrintMessage = lsPrintMessage + "Full documentation English " + pdtPrintDetails.Rows[lirow]["COPY_TYPE"].ToString().Trim() + " has been sent to printer " + cmbPrinter.SelectedValue.ToString().Trim() + Environment.NewLine;
}
else
lsPrintMessage = "This printer " + cmbPrinter.SelectedValue.ToString().Trim() + " is not installed on server,cannot print";
}
This line causes the issues
System.Drawing.Printing.PrinterSettings.PrinterName =cmbPrinter.SelectedValue.ToString().Trim();
If i remove this line,the printer prints to my default printer and print comes correctly
I tried various combinations of setting printer name with the below values,all print junk values
1)printerSettings.PrinterName= "Dyna_Offshore";
2)pSettings.PrinterSettings.PrinterName= "Dyna_Offshore";
3)System.Drawing.Printing.PrinterSettings.PrinterName = "\\\\My PC IP\\Dyna_Offshore";
I tried setting printer name on report document like this ,but the code ignores this setting and takes PrinterName from printerSettings
1)ObjDoc.PrintOptions.PrinterName= "Dyna_Offshore";
it was printer driver issue.In WPF VS2017 ,when we are printing what ever driver name is printed on the physical printer .The printer needs to be installed with the exact driver name .If there is even a slight mismatch in the driver name ,it was causing junk values to be printed when printing programmatically through VS2017.Normal printing will work if there is mismatch in drivers.Also this issue is not there in VS2010 with Webforms .I have tested this in 2 printers in different countries and i was able to print successfully.

Why do I have to call the initialization command twice? (otherwise i get the output "t#")

I have an Epson TM-T88VI printer and use the Microsoft.PointOfService.PosPrinter in C# for printing.
I have the following two test functions:
public static void printerTestFunction(string printerName)
{
PosExplorer explorer = new PosExplorer();
DeviceInfo di = explorer.GetDevice("PosPrinter", printerName);
PosPrinter printer = (PosPrinter)explorer.CreateInstance(di);
printer.Open();
printer.Claim(10000);
printer.DeviceEnabled = true;
printer.AsyncMode = false;
string init = System.Text.ASCIIEncoding.ASCII.GetString(new byte[] { 27, 64 });
string totalCut = System.Text.ASCIIEncoding.ASCII.GetString(new byte[] { 27, 105 });
string cmd = init + "A€A\nB€B\n\n\n\n\n\n\n\n" + totalCut;
printer.PrintNormal(PrinterStation.Receipt, cmd);
}
public static void printerTestFunction2(string printerName)
{
PosExplorer explorer = new PosExplorer();
DeviceInfo di = explorer.GetDevice("PosPrinter", printerName);
PosPrinter printer = (PosPrinter)explorer.CreateInstance(di);
printer.Open();
printer.Claim(10000);
printer.DeviceEnabled = true;
printer.AsyncMode = false;
string init = System.Text.ASCIIEncoding.ASCII.GetString(new byte[] { 27, 64 });
string totalCut = System.Text.ASCIIEncoding.ASCII.GetString(new byte[] { 27, 105 });
string cmd = init + init + "A€A\nB€B\n\n\n\n\n\n\n\n" + totalCut;
printer.PrintNormal(PrinterStation.Receipt, cmd);
}
The only difference between the two functions: in function2 i send a "double" init to the printer (see string cmd = initialization).
Normally I would expect the two functions to lead to the same result. But that is not the case.
After calling "printerTestFunction2" i get the output as expected:
A€A
B€B
When i restart my program and call "printerTestFunction" i get the following output:
t#A€A
B€B
I also tested with other functions. The first init command is always printed as "t#" except if I init the printer twice.
Can somebody explain that behaviour?
This is because, as I answered the previous question, the application is sending the initialization command directly.
Why is the “€” character only printed before printer initialization and not after the initialization?
If you are using POS for.NET (including OPOS/JavaPOS), you should not use the initialization command (ESC#) or similar commands to change the mode or settings.
If you want to do something, call the method or put the POSPrinter escape sequence defined in UnifiedPOS into the print request string.
I think its may cause because you didn't add "Esc #" in the end of command. In Page335 example, there are point out every program have "Start Job" and "End Job" is the same of code "Esc #"(same to new "byte[] { 27, 64 }" )
But it looks like you didn't add this at the end of the command, so if next time you command "Esc #", actually is the last time program of "End Job"? I guess this may be the reason why there have something like "t#" before output?
So you can try something changes like:
string cmd = init + "A€A\nB€B\n\n\n\n\n\n\n\n" + totalCut + init;
If ture, it may success at the second time.

PrintQueue.Refresh don't show the status of printer

I need to run a Windows Service of server X to show the status of all printers: Out of paper, no toner, etc.
The service is running on a machine but of course not all printers are installed on it. Even when the printers are installed on the machine, we do NOT have the status of the printers!
The only thing I was able to do is to remove the paper, print a test page (notepad), and now I can see that I'm missing paper with the code below, but as you might thing, this is not doable: I don't want to send a test page to every printers of the network every 10 minutes or so!
I try to query PrintQueue.Refresh but status is not updating, I don't see that the printer tray is open (or missing paper, or no toner, whatever I do with the printer.)
BTW, Win32_printer don't show me a better result.
NOTE:
MonitoringWS is the web service that can access the database.
Printers is the list of printers that we want to query.
This is what I try to do.
var printServers = GetListOfPrinterServers();
var listPrinters = printers as List<Printer> ?? printers.ToList();
foreach (
var printServer in
printServers.Select(
server => new PrintServer(server, PrintSystemDesiredAccess.EnumerateServer)))
{
printServer.Refresh();
var printQueues = printServer.GetPrintQueues();
foreach (var printQueue in printQueues)
{
var queue = printQueue;
var printersFound = listPrinters.Where(p =>
string.Equals(p.PrinterName, queue.FullName,
StringComparison.OrdinalIgnoreCase));
foreach (var printer in printersFound)
{
printQueue.Refresh();
Debug.WriteLine(string.Format("{0} {1}", printQueue.FullName, printQueue.HostingPrintServer.Name) );
var pm = new MonitoringWS.PrinterMonitoring
{
FkPrinter = printer.PkPrinter,
QueueStatus = printQueue.QueueStatus,
DriverName = printQueue.QueueDriver.Name,
MonitoringDateTime = DateTime.Now
};
printerMonitorings.Add(pm);
}
}
}
I found a way: SNMP. I use library SNMP# at http://www.snmpsharpnet.com/ and I implement RFC 2790: https://www.rfc-editor.org/rfc/rfc2790 .
With that, when the printer support that standard and when SNMP is active, I got the status of the printer (no toner, no paper, paper jam, etc.)
Thanks everybody for your help.

C# PrintQueue AddJob printingHandle throws null exception

I'm trying to print a file with C#. I have made some headway in listing off all the printers and then wrote some simple logic to select the correct printer:
var server = new PrintServer();
var queues = server.GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections }).ToList();
int count = 0;
foreach (var q in queues)
{
Console.WriteLine(count++ + " " + q.Name);
}
int iSelection = 0;
while (true)
{
Console.Write("Select printer: ");
string selection = Console.ReadLine();
if (int.TryParse(selection, out iSelection) && iSelection >= 0 && iSelection < queues.Count())
{
break;
}
else
{
Console.WriteLine("Bad selection, try again.");
}
}
The next step, as for the posts I've seen on this site, is that you need to select the specific queue, and then add a job, grab the job stream, and write to the stream (at least that's how I want to try to do it, unless it's wrong?)
var queue = queues[iSelection];
var job = queue.AddJob(#".\Test.txt");
var stream = job.JobStream;
var file = File.ReadBytes(#".\Test.txt");
stream.Write(file, 0, file.Length);
When I do this, the program crashes at the line with AddJob. Specifically,
System.ArgumentNullException: 'Value cannot be null, Parameter name: printingHandler'
Now, I think I understand what the issue is. I had been playing with System.Drawing.Printing.PrintDocument yesterday, but I am trying to find a solution that allows me to print files, rather than manually draw them out and them print them. Ultimately, the goal in the future is to be able to print out text and PDF files (I was hoping that this solution would allow me to open a PDF file and dump the bytes into this stream, but I don't know if that's the correct way to this?)
Anyway, the exception I got I think is something similar to PrintDocument's PrintPageEventHandler, I need to add a callback to the PrintQueue somehow that tells it the font, color, font size, etc. Problem is that I see nothing for PrintQueue that allows me to add a handle for it to fix this issue.
What can I do to fix this exception?
I was having this issue as well. Eventually I found out that we need to call into Refresh() of the selected PrintQueue instance and before calling AddJob().

I'm trying to send esc/pos data to a VKP80II printer in C# trough usb

im trying to send a string data to my vkp80ii printer, i did this with a raw binary file and it printed but when i try to use string it doesn't od anything.
Any help?
class VKP80II_Driver
{
static USBH_Printer printer;
static AutoResetEvent printerConnected = new AutoResetEvent(false);
public static void Main()
{
// Subscribe to USBH event.
USBHostController.DeviceConnectedEvent += DeviceConnectedEvent;
// wait for printer to be connectoed.
printerConnected.WaitOne();
// Get file to print
//byte[] buffer = Resources.GetBytes(Resources.BinaryResources.beep);
byte[] buffer = StrToByteArray("$0AHello World");
// Printing can take a long time, give it a 5 seconds timeout here
printer.SendData(buffer, 0, buffer.Length, 5000);
// Sleep forever
Thread.Sleep(Timeout.Infinite);
}
// Is printer connected event
static void DeviceConnectedEvent(USBH_Device device)
{
if (device.TYPE == USBH_DeviceType.Printer)
{
printer = new USBH_Printer(device);
printerConnected.Set();
}
}
// Parse string object to byte array
static byte [] StrToByteArray(string str)
{
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
return encoding.GetBytes(str);
}
}
answer to the question
is i had to send real bytes to to printer
example:
byte[] newByte = new bytes [] {0x0A};
printer.SendData(newByte, 0, buffer.Length, 5000);
When I need such a functionality I couldn't find any library related to that.
So I decided to make one.
ESC-POS-USB-NET is a free and open source .NET (C#) Implementation of the Epson ESC/POS Printing using USB Device Driver.
This library is available Open Source # MIT license.
You can install from Nuget Packages
follow the steps below:
⏳ Installation
Install Strapi with this Quickstart command to create a project instantly:
(Use nuget package manager to install (recommended))
Install-Package ESC-POS-USB-NET
or
(Use .Net Cli to install)
dotnet add package ESC-POS-USB-NET
This command install ESC-POS-USB-NET with your project.
Enjoy 🎉
❤️ Example Using C#
Import ESC_POS_USB_NET Printer Class:
using ESC_POS_USB_NET.Printer;
You can find printer name from (Windows): Control Panel->Hardware and Sound->Devices and Printers-> Your Printer's Name
Test Print:
Printer printer = new Printer("Printer Name");
printer.TestPrinter();
printer.FullPaperCut();
printer.PrintDocument();
Print Image:
Printer printer = new Printer("Printer Name");
Bitmap image =new Bitmap ( Bitmap.FromFile("Icon.bmp"));
printer.Image(image);
printer.FullPaperCut();
printer.PrintDocument();
Print Barcodes:
Printer printer = new Printer("Printer Name");
printer.Append("Code 128");
printer.Code128("123456789");
printer.Separator();
printer.Append("Code39");
printer.Code39("123456789");
printer.Separator();
printer.Append("Ean13");
printer.Ean13("1234567891231");
printer.FullPaperCut();
printer.PrintDocument();
Open Drawer:
Printer printer = new Printer("Printer Name");
printer.OpenDrawer();
printer.PrintDocument();
Typography Test:
Printer printer = new Printer("Printer Name");
printer.Append("NORMAL - 48 COLUMNS");
printer.Append("1...5...10...15...20...25...30...35...40...45.48");
printer.Separator();
printer.Append("Text Normal");
printer.BoldMode("Bold Text");
printer.UnderlineMode("Underlined text");
printer.Separator();
printer.ExpandedMode(PrinterModeState.On);
printer.Append("Expanded - 23 COLUMNS");
printer.Append("1...5...10...15...20..23");
printer.ExpandedMode(PrinterModeState.Off);
printer.Separator();
printer.CondensedMode(PrinterModeState.On);
printer.Append("Condensed - 64 COLUMNS");
printer.Append("1...5...10...15...20...25...30...35...40...45...50...55...60..64");
printer.CondensedMode(PrinterModeState.Off);
printer.Separator();
printer.DoubleWidth2();
printer.Append("Font Width 2");
printer.DoubleWidth3();
printer.Append("Font Width 3");
printer.NormalWidth();
printer.Append("Normal width");
printer.Separator();
printer.AlignRight();
printer.Append("Right aligned text");
printer.AlignCenter();
printer.Append("Center-aligned text");
printer.AlignLeft();
printer.Append("Left aligned text");
printer.Separator();
printer.Font("Font A", Fonts.FontA);
printer.Font("Font B", Fonts.FontB);
printer.Font("Font C", Fonts.FontC);
printer.Font("Font D", Fonts.FontD);
printer.Font("Font E", Fonts.FontE);
printer.Font("Font Special A", Fonts.SpecialFontA);
printer.Font("Font Special B", Fonts.SpecialFontB);
printer.Separator();
printer.InitializePrint();
printer.SetLineHeight(24);
printer.Append("This is first line with line height of 30 dots");
printer.SetLineHeight(40);
printer.Append("This is second line with line height of 24 dots");
printer.Append("This is third line with line height of 40 dots");
printer.NewLines(3);
printer.Append("End of Test :)");
printer.Separator();
printer.FullPaperCut();
printer.PrintDocument();
🎈 Features:
Alignment: Left, Right and Center alignment.
BarCode: Code128, Code39, Ean13 barcodes are supported.
Drawer: Drawer Open facility.
Font Mode: Supported Bold, Underline, Expanded, Condensed modes.
Change Font: Change font to device specified FontA, FontB, FontC, FontD, FontE, SpecialFontA and SpecialFontB.
Font Width: Supported Normal, DoubleWidth2 and DoubleWidth3.
Image: Print BMP Image.
Paper Cut: Cut paper with Full & Partial Cut.
QrCode: Support 2D barcode (QrCode).

Categories