I'm trying to cut the paper pragmatically by sending paper cut command to the printer (Epson TM U220 with USB port).
I used the printer with Generic/Text Only Driver and Epson printer port which I found after installing
Epson advanced printer driver.
Printer command code is (GS V m), where m = 0,1,48 or 49 which I found on the device manual.
I would like to know how to send these command to printer by StringWriter.
I use Generic/Text Only printer because it's much faster than using Epson driver.
I'm really new to C# windows and please anyone kindly provide me some lines of code to achieve this. I've been surfing the web for several days and still not found the answer yet. I think I need to send printer command as byte but I don't know how to do :(
Thank you very much Hans. Now I can send Paper cut command by using Microsoft RawPrinterHelper class. I've been seeking this solution for six days. Here is what I've done.
string GS = Convert.ToString((char)29);
string ESC = Convert.ToString((char)27);
string COMMAND = "";
COMMAND = ESC + "#";
COMMAND += GS + "V" + (char)1;
PrintDialog pd = new PrintDialog();
pd.PrinterSettings = new PrinterSettings();
if (DialogResult.OK == pd.ShowDialog(this))
{
RawPrinterHelper.SendStringToPrinter(pd.PrinterSettings.PrinterName, COMMAND);
}
For those printing with netcat (really easy way to print something without installing any driver), to cut the paper:
echo -e "\x1B#\x1DV1" | nc printer.ip 9100
Same string like in the c# version, but mapped to hex: \x1B = ESC and \x1D = GS.
s = Replace(s, "<KESME>", Chr(27) + Chr(105), 1) ' Termal Printer
Chr() +chr()
Related
I have writen some simple C# Tool that Prints PDFs with the Help of SpirePDF
In the Tool i can select The Printer and its PaperTray
I have 2 Printers here and they are working fine with my code (The correct tray is used)
On an other machine with other Printers, it doesnt work, the correct Printer is choosen, but the PaperTray is alway the same (Manual Feed), no matter which Tray i choose.
printDocument.PrinterSettings.PrinterName = PrinterSettings.InstalledPrinters[MyPrinterConfiguration.GetPrinterIndex(#"invoice_print")];
printDocument.DefaultPageSettings.PaperSource = printDocument.PrinterSettings.PaperSources[MyPrinterConfiguration.GetPrinterTrayIndex(#"invoice_print")];
MyPrinterConfiguration is an Dictionary that hold the indexes of the Trays and Printer on the System.
Are there any other methods to set the PaperSource for this Document?
My Printers are from Samsung and Brother
the others from HP and Brother (both are not working) so it seem not to be a driver Problem.
I have found a solution:
Setting the PaperSource in self-created PrinterSettings seems not to work for some Printers, but when i make a Printdialog, let the User choose the Settings (PaperSource, PaperType and so on) and take theese settings (unchanged) to apply them on the PrintDocument, then it works for all my testet printers.
I think PrinterSettings from PrintDialog have other or more characteristics than i can set programaticly.
if (printDialog.ShowDialog() == DialogResult.OK) {
gpsMyPrintSettings.SetSettingsForType( "badge", (PrinterSettings) printDialog.PrinterSettings.Clone() );
}
printDocument.PrinterSettings = gpsMyPrintSettings.GetSettingsForDocumentType( "badge" );
printDocument.Print();
I am very confused right now and I need someone explain why one thing isn't working yet another is. I am using the RawPrinterHelper to send commands to a receipt printer. Right now trying to send the command 29,109 (cut paper)
found here for the TM-T88.
I figured this should do the trick:
RawPrinterHelper.SendStringToPrinter(pName, ASCIIEncoding.ASCII.GetString(new byte[] { 29, 109 }));
It didn't work and doing some research I found this code;
string GS = Convert.ToString((char)29);
string ESC = Convert.ToString((char)27);
string COMMAND = "";
COMMAND = ESC + "#";
COMMAND += GS + "V" + (char)1;
RawPrinterHelper.SendStringToPrinter(pd.PrinterSettings.PrinterName, COMMAND);
This works perfectly. Here is my confusion:
Why didn't my first code work?
Why is there so much more needed in the string?
Why is it using 29 instead of 109?
What is the "#" for?
What is the "V" for?
For example, I am really at a loss on how to send the command print logo: 28,112,1,0.
Why didn't my first code work?
The documentation which you've linked to shows that 27, 109 is the sequence to send for the TM-T88. You code which isn't working, is sending 29, 109.
If you look at the code which is working, you'll see that 27 (ESC) is sent first. ESC is a typical message to a printer that commands are to follow rather than text to print.
Why is there so much more needed in the string?
It's not so much needed, it's doing additional things, and using a different command to cut the paper as I'll show below.
Why is it using 29 instead of 109?
What is the "#" for?
What is the "V" for?
Have a look at the commands here: https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=82
Full sequence of the working command is ESC # GS V 1
ESC # is "Initialize printer"
GS V is described as "Select cut mode and cut paper". I assume the "1" after it is the mode being set, but as it has "cut paper" in the description that would by why it is cutting the paper.
I create a program where its objective is to monitor the Fixed asset. One part of the system is print barcode in the zebra z4m plus 203dpi. how can I print on that device? I already try but the printed barcode is blurred. I use the bitmap and print it using the PrintDocument function of c#.
You have to create a string with your ZPL code then send it to Z4M.
Can see how to do here : .NET code to send ZPL to Zebra printers
or with SharpZebra :
1) Install a Zebra Printer so it's accessible on your Print Queue (we're going to assume the name of your printer is ZDesigner S4M-203dpi ZPL).
2) Add a reference to the SharpZebra libraries to your project
3) Write the code below to print a label into a class
4) Run the code
PrinterSettings ps = new PrinterSettings();
ps.PrinterName = "ZDesigner S4M-203dpi ZPL";
ps.Width = 203 * 4;
ps.Length = 203 * 6;
ps.Darkness = 30;
List<byte> page = new List<byte>();
page.AddRange(ZPLCommands.ClearPrinter(ps));
page.AddRange(ZPLCommands.TextWrite(10, 150, ElementDrawRotation.NO_ROTATION, ZebraFont.STANDARD_NORMAL, 15, "Hello World!"));
page.AddRange(ZPLCommands.PrintBuffer(1));
new SpoolPrinter(ps).Print(page.ToArray());
As far i know, you could use ZebraDesigner (check it on Zebra site) to dessing your label.
ZebraDesigner creates a ZPL (or EPL) file this that label dessign.
You can send this files to the printer using Serial Communication and the device prints the label
I've been building a POS application for a restaurant/bar. The design part is done and for the past month I've been coding it. Everything works fine except now I need to print. I have to print to a receipt printer connected to the computer running the software and later I'll try to print in a remote printer like a kitchen one.
I've searched for help in the matter only to find that the standard for printing in these types of printers is using POS for .NET. The thing is, this is now a bit outdated or at least it hasn't had any updates since a couple of years. There's a lot of questions being asked on how to use this library and most of the answers aren't quite easy to follow. So if anybody could give a step by step help on printing like a simple phrase ("Hello World") on a receipt printer i would be very grateful. I'm using visual studio 2012 running on a 64 bit windows 7 and i'm coding WPF in c#.
I know this is an old post, but for those still looking for a solution, I can tell you what I did.
After spending many hours messing with OPOS and POS for .Net, I ended up just abandoning those and just using the built-in System.Drawing.Printing libraries. The OPOS and POS for .Net ended up being a pain to get working and ultimately didn't work as well as the built-in libraries.
I'm using an Epson TM-T20II receipt printer.
Here's some code that worked well for me.
public static void PrintReceiptForTransaction()
{
PrintDocument recordDoc = new PrintDocument();
recordDoc.DocumentName = "Customer Receipt";
recordDoc.PrintPage += new PrintPageEventHandler(ReceiptPrinter.PrintReceiptPage); // function below
recordDoc.PrintController = new StandardPrintController(); // hides status dialog popup
// Comment if debugging
PrinterSettings ps = new PrinterSettings();
ps.PrinterName = "EPSON TM-T20II Receipt";
recordDoc.PrinterSettings = ps;
recordDoc.Print();
// --------------------------------------
// Uncomment if debugging - shows dialog instead
//PrintPreviewDialog printPrvDlg = new PrintPreviewDialog();
//printPrvDlg.Document = recordDoc;
//printPrvDlg.Width = 1200;
//printPrvDlg.Height = 800;
//printPrvDlg.ShowDialog();
// --------------------------------------
recordDoc.Dispose();
}
private static void PrintReceiptPage(object sender, PrintPageEventArgs e)
{
float x = 10;
float y = 5;
float width = 270.0F; // max width I found through trial and error
float height = 0F;
Font drawFontArial12Bold = new Font("Arial", 12, FontStyle.Bold);
Font drawFontArial10Regular = new Font("Arial", 10, FontStyle.Regular);
SolidBrush drawBrush = new SolidBrush(Color.Black);
// Set format of string.
StringFormat drawFormatCenter = new StringFormat();
drawFormatCenter.Alignment = StringAlignment.Center;
StringFormat drawFormatLeft = new StringFormat();
drawFormatLeft.Alignment = StringAlignment.Near;
StringFormat drawFormatRight = new StringFormat();
drawFormatRight.Alignment = StringAlignment.Far;
// Draw string to screen.
string text = "Company Name";
e.Graphics.DrawString(text, drawFontArial12Bold, drawBrush, new RectangleF(x, y, width, height), drawFormatCenter);
y += e.Graphics.MeasureString(text, drawFontArial12Bold).Height;
text = "Address";
e.Graphics.DrawString(text, drawFontArial10Regular, drawBrush, new RectangleF(x, y, width, height), drawFormatCenter);
y += e.Graphics.MeasureString(text, drawFontArial10Regular).Height;
// ... and so on
}
Hopefully it helps someone skip all the messing around with custom drivers. :)
POS for .NET is probably the way to go.
Most receipt printer manufacturers will provide an OPOS service object.
And as this MSDN article states, POS for .NET is compatible with OPOS v1.8 service objects.
OPOS / UPOS (on which POS for .NET is based) is IMHO a poorly-designed API (designed by device manufacturers rather than application developers), but it's the best you have today.
I don't have any specific samples but the basics are the same as OPOS - you need to Open, Claim, Enable a device, then you can call its methods (such as Print). You might try looking at an OPOS sample, for example this PosPrinter1 sample, which will probably be very similar to POS for .NET.
This blog has some information about setting up POS for .NET that might be helpful.
UPDATE
Here's a VB Hello World for an OPOS printer. You first need to create a printer and add it to the registry with the required Logical Device Name = LDN. I believe the Epson ADK includes a utility to add a printer in the registry. This utility can also perform a health check on the printer to check it is installed correctly. Once you've done this, it should be easy enough to adapt the code below to POS for .NET
OPOSPOSPrinter.Open "MyPrinter" ' LDN of your printer
OPOSPOSPrinter.Claim 500 ' Timeout
OPOSPOSPrinter.DeviceEnabled = True
'- Print
OPOSPOSPrinter.PrintNormal 2, "Hello world"
'- Close the printer
If OPOSPOSPrinter.Claimed then
OPOSPOSPrinter.Release
End If
OPOSPOSPrinter.Close
.NET Printing
Printing under .NET isn't too difficult. Take a look here and on msdn.
Printing to a POS / receipt printer will be the same as printing to any other printer, assuming it is a Windows printer, network or otherwise. If you are using a serial printer, things may be a little more difficult because you will more then likely need to use manufacturer specific API's, fortunately though most good POS printers these days are fully supported by the OS.
First, you will need to add a reference to System.Printing dll to your project.
Then printing is as simple as
private void PrintText(string text)
{
var printDlg = new PrintDialog();
var doc = new FlowDocument(new Paragraph(new Run(text)));
doc.PagePadding = new Thickness(10);
printDlg.PrintDocument((doc as IDocumentPaginatorSource).DocumentPaginator, "Print Caption");
}
To use..
PrintText("Hello World");
You can also leverage the PrintDialog.PrintVisual and define your document using xaml template.
The print settings can be set using the PrintDialog properties.
Getting the printer you want to print to
private PrintQueue FindPrinter(string printerName)
{
var printers = new PrintServer().GetPrintQueues();
foreach (var printer in printers)
{
if (printer.FullName == printerName)
{
return printer;
}
}
return LocalPrintServer.GetDefaultPrintQueue();
}
A few things to keep in mind though when printing to a receipt printer, you will need to take into account formatting. More specifically you will need to consider the width of your page and how many characters you can fit on each line; this was a lot of trial and error for me, especially with different font sizes.
In most cases you don't really need to worry about paging, the printer will cut the paper automatically when it has completed your document.
If you want to print at the full speed of the printer, you will probably need to use printer-specific escape codes, and generate the "raw" output.
Have a look at Michael Buen's answer to this SO question, especially the UPDATE bit.
Update: This may not be "Pairing". This may just need to have a service started and bound to a port. However, this code is not storing it either. I need the device to be stored even after the application is closed.
I am building a program specifically suited for Zebra RW 420's on a Windows Mobile 6 Handheld device. The application needs to allow a mobile device to pair with the printer on COM1. I believe I am very close to getting it, but I can't get the pair request to work.
I am able to communicate with the printer and even print by directly connecting and printing, but I can't get the mobile device to actually pair with it. I've tried a variation of pins to include null, "1", "0000", and "1234". No matter what, the method always returns false. Any suggestions or ideas why this might be failing? I can pair the device just find in the WM6 Bluetooth menu, but not in my application.
It might be important to note that the little light bulb icon on the printer comes on when the program says it is attempting to pair, but after about 5 to 10 seconds, it fails.
BluetoothSecurity.PairRequest(device, "1"))
Additional Information:
I've successfully paired with my Android phone using this code.
I then logged in and set a PIN on the Zebra printer. However, this code still fails to pair with the printer even when I know the pin is correct / set in the printer.
From https://km.zebra.com/kb/index?page=answeropen&type=open&searchid=1336682809706&answerid=16777216&iqaction=5&url=https%3A%2F%2Fkm.zebra.com%2Fkb%2Findex%3Fpage%3Dcontent%26id%3DSO8031%26actp%3Dsearch%26viewlocale%3Den_US&highlightinfo=6292341,26,43#
Zebra Bluetooth enabled mobile printers are 'slave' devices only. The printers will pair with any 'master' device that tries to make a valid connection. Since only a master device can initiate a connection, the printer does not store pairing data, that function is always done on the master device. The printer can only be connected to one master device at a time, but any number of master devices that have stored pairing information for the printer would be able to initiate a connection to the printer without having to rediscover it.
I'm guessing that this means the InTheHand.Net BluetoothSecurity.PairRequest might not work for this type of pairing?
In the Bluetooth section of the WM handheld, under the "Devices" tab, I can add the device. I need to essentially do that. I need to register the device in that list and then set it to use COM 1 in the "COM Ports" section. The application I am using doesn't actually print. It's sole purpose is to prepare the printer for other applications.
The quote from Zebra make it sounds as pairing is actually not required at all. Are you printing from your app? If so just connect to the SPP service and send the text.
BluetoothAddress addr = ...
Guid serviceClass;
serviceClass = BluetoothService.SerialPort;
var ep = new BluetoothEndPoint(addr, serviceClass);
var cli = new BluetoothClient();
cli.Connect(ep);
Stream peerStream = cli.GetStream();
peerStream.Write ...
(From General Bluetooth Data Connections)
The Zebra Mobile Printer needed to be properly configured before pairing with this method will work. Here is what I did:
First, I ran the following commands on the printer:
.
! U1 setvar "bluetooth.authentication" "setpin"
! U1 getvar "bluetooth.authentication"
! U1 getvar "bluetooth.enable"
! U1 getvar "bluetooth.discoverable"
! U1 setvar "bluetooth.bluetooth_pin" "0000"
! U1 getvar "bluetooth.bluetooth_pin"
Then, the application with this code ran successfully.
.
int pair_req = 0;
try
{
if (BluetoothSecurity.SetPin(device, "0000")) {
while (status == false && pair_req < 3)
{
++pair_req;
status_box.Text = status_box.Text + '\n' + "Attempt " + pair_req.ToString();
status_box.Update();
if (BluetoothSecurity.PairRequest(device, "0000"))
{
status = true;
client.Refresh();
status_box.Text = "Paired Successfully.";
status_box.Update();
Thread.Sleep(5000);
}
else
{
status = false;
}
}
}
}
catch (ArgumentNullException e)
{
status_box.Text = "Pair failed.";
status_box.Update();
Thread.Sleep(5000);
}
status_box.Update();
Thread.Sleep(400);