RawPrinterHelper and commands to Epson printer - c#

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.

Related

Chrome remote desktop Console.ReadKey yelds System.ConsoleKey.Packet instead of keystroke

This is more of a curiosity to be completely honest.
Inside a console project I am developing I request input from the user in a looped form of this:
ConsoleKey response;
Console.Write("Write messages to log? [y/n] ");
response = Console.ReadKey(false).Key;
assume 4 cases:
case 1: Pressing the 'y' key on a keyboard directly atached to the pc running the software.
case 2: Connecting from another computer trough remote desktop connection and pressing the 'y' key on that machine.
case 3: Using on screen keyboard and press the 'y' key trough clicking on it (remotely or locally had no difference)
case 4: Connecting from another machine (specifically a phone) trough chrome remote desktop and pressing the 'y' key.
In case 1, 2 and 3, 'response' will contain 'Y'.
In case 4 'response' will instead contain System.ConsoleKey.Packet aka enum 231 PACKET key (used to pass Unicode characters with keystrokes).
I have tried the same thing trough a second pc and I noticed this behavior does not appear to occurr.
The most interesting thing is that the console shows me this
Write messages to log? [y/n] y
From this I evince that the keystroke is indeed received but handled incorrectly by my code.
I am at a loss as to how to proceed.
Console.ReadLine yelds the correct keystrokes but i would prefer to use Console.ReadKey if possible.
Is this specific behavior for phone keyboards? How would I obtain the actual key?
How would I obtain the actual key?
The MSDN docs for ConsoleKey.Packet doesn't say anything useful, so I found references to ConsoleKey in the source which lead here. That's casting ir.keyEvent.virtualKeyCode to a ConsoleKey where ir is an InputRecord.
A quick google finds the WinApi equivalent is INPUT_RECORD, and chasing the docs through KEY_EVENT_RECORD leads to this doc of Virtual-Key codes, which contains some more docs for VK_PACKET:
Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP
The Remarks for KEYBDINPUT say:
INPUT_KEYBOARD supports nonkeyboard-input methods—such as handwriting recognition or voice recognition—as if it were text input by using the KEYEVENTF_UNICODE flag. If KEYEVENTF_UNICODE is specified, SendInput sends a WM_KEYDOWN or WM_KEYUP message to the foreground thread's message queue with wParam equal to VK_PACKET. Once GetMessage or PeekMessage obtains this message, passing the message to TranslateMessage posts a WM_CHAR message with the Unicode character originally specified by wScan. This Unicode character will automatically be converted to the appropriate ANSI value if it is posted to an ANSI window.
From my searching it doesn't look like .NET implements this mechanism for you, so you might have to do it yourself!
I'm afraid I've no idea why it's happening in your case however...
I just ran into this issue too! In my case, it only happened when connecting to my development pc from a phone as well. (I was using the RDP app)
Here's what I came up with today that works!
public static bool Confirm(string prompt)
{
Console.Write($"{prompt} [y/n] ");
char letter;
do
{
letter = char.ToLower(Console.ReadKey(true).KeyChar);
} while (letter != 'y' && letter != 'n');
Console.WriteLine(letter);
return letter == 'y';
}
Thanks for confirming that I'm not the only one with the issue!

How can I enter an email address into text input field in Edge using Selenium WebDriver?

I have the following program:
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Edge;
namespace ConsoleApplication1
{
static class Program
{
static void Main()
{
//var driver = new ChromeDriver();
var driver = new EdgeDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(20));
driver.Navigate().GoToUrl("http://www.cornelsen.de/shop/registrieren-lehrer");
driver.FindElement(By.Id("email")).SendKeys("dummy#user.de");
}
}
}
When I run this in Chrome or any other browser aside from Edge, then the email adress is entered correctly. But if I try the same thing in Edge, the "#" character is missing. The field displays only "dummyuser.de".
Any idea what I can do?
As a workaround, you can set the input value directly via ExecuteScript():
IWebElement email = driver.FindElement(By.Id("email"));
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
string script = "arguments[0].setAttribute('value', 'arguments[1]');";
js.ExecuteScript(script, email, "dummy#user.de");
Or, what you can do is to create a fake input element with a predefined value equal to the email address. Select the text in this input, copy and paste into the target input.
Not pretty, but should only serve as a workaround:
// create element
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
string script = #"
var el = document.createElement('input');
el.type = 'text';
el.value = 'arguments[0]';
el.id = 'mycustominput';
document.body.appendChild(el);
";
js.ExecuteScript(script, "dummy#user.de");
// locate the input, select and copy
IWebElement myCustomInput = driver.FindElement(By.Id("mycustominput"));
el.SendKeys(Keys.Control + "a"); // select
el.SendKeys(Keys.Control + "c"); // copy
// locate the target input and paste
IWebElement email = driver.FindElement(By.Id("email"));
email.SendKeys(Keys.Control + "v"); // paste
It wasn't as easy as I thought after all. Issues with alecxe's answer:
arguments[0].setAttribute('value', '...'); works only the first time you call it. After calling element.Clear();, it doesn't work any more. Workaround: arguments[0].value='...';
The site doesn't react on the JavaScript call like it would on element.SendKeys();, e.g. change event is not invoked. Workaround: Send the first part of the string up to the last "forbidden" character via JavaScript, the rest via WebElement.SendKeys (in this particular order, bc if you do another JavaScript call to the same field after SendKeys(), there will occur no change event either).
I also realized that there are more "forbidden" characters in Edge, e.g. accented or Eastern European ones (I'm Central European). The problem with 2. is that the last character might be a forbidden character. In this case, I append a whitespace. Which of course affects the test case behavior, but I haven't had any other idea.
Full C# code:
public static void SendKeys(this IWebElement element, TestTarget target, string text)
{
if (target.IsEdge)
{
int index = text.LastIndexOfAny(new[] { '#', 'Ł', 'ó', 'ź' }) + 1;
if (index > 0)
{
((IJavaScriptExecutor) target.Driver).ExecuteScript(
"arguments[0].value='" + text.Substring(0, index) + "';", element);
text = index == text.Length ? Keys.Space : text.Substring(index);
}
}
element.SendKeys(text);
}
This problem used to occur in old browsers. Apparently it returned in Edge.
You can try sending the string in pieces
IWebElement email = driver.FindElement(By.Id("email"));
email.SendKeys("dummy");
email.SendKeys("#");
email.SendKeys("user.de");
Or try using # ASCII code
driver.FindElement(By.Id("email")).SendKeys("dummy" + (char)64 + "user.de");
Try to clear the Text field first.
try following
driver.FindElement(By.Id("email")).clear().SendKeys("dummy#user.de");
Have you tried Copy Paste?
Clipboard.SetText("dummy#user.de");
email.SendKeys(OpenQA.Selenium.Keys.Control + "v");
Hope it could help.
I just added one extra line to click on text field and then send keys, I tried this and its working for me.
Code is written in java, you can change that to any other, if you want.
//INITIALISE DRIVER
WebDriver driver = null;
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.navigate().to("http://www.cornelsen.de/shop/registrieren-lehrer");
driver.manage().window().maximize();
//CLICK EMAIL FIELD, JUST TO HAVE FOCUS ON TEXT FIELD
driver.findElement(By.id("email")).click();
driver.findElement(By.id("email")).sendKeys("dummy#user.de");
I'm the Program Manager for WebDriver at Microsoft. I just tried to reproduce your issue on my home machine (Windows 10 build 10586) and couldn't reproduce. Your exact test entered the '#' symbol fine.
You should check if you have the latest version of Windows 10 and WebDriver. If you hit the Windows key and type "winver" and hit enter it'll open a popup with the Windows version info. You want it to say
Microsoft Windows
Version 1511 (OS Build 10586.104)
This is the latest version of Windows 10 released to the public. If you have this version you'll also need the corresponding version of WebDriver found here:
http://www.microsoft.com/en-us/download/details.aspx?id=49962
Note that if the build is 10240 that you're on the original release build. Our November update added substantial support for new features (like finding elements by XPath and more!) along with bug fixes which might explain your issues.
Lastly I should note we have an Insiders release as well for WebDriver to match with the Insiders program. If you're subscribed to the Insiders program and want to see the newer features and bug fixes for WebDriver you can find the download here:
https://www.microsoft.com/en-us/download/details.aspx?id=48740
Note that it currently supports build 10547 which was actually before the November update. It'll be updated very shortly (next couple of days) to support the latest Windows Insiders flight, build 14267.
Sorry but I not agree with the last comment (Program Manager for WebDriver at Microsoft). I can reproduce the problem. This is my configuration:
Target Machine (Hub node where tests are run):
Win 10 build 10585.104
MS Edge 25.10586.0.0
MS EdgeHTML 13.10586
Selenium framework:
SeleniumHQ (for Java): 2.48.0
I am using Selenium Grid to run my suite. In this case, I was only doing conceptual test of Egde implementing a basic test:
1. Start Hub in local machine (Win 7) opening console (administrator privileges)
2. Register Node in Hub in target remote machine (Win 10 build 10585) opening console (in this case without administrator privileges because in other way edge hangs when create new session).
Setting up my grid and checking that everything is ok when I try to write my account name in login page I can not see the # and my basic test fails (wrong credentials).
I have introduced # by hand in the moment edge is opened (interrupt point) and I can see symbol.
I have sent "###############" to the text field and I can not see any. In summary, I have tried many things and I can not see #
When I started with Web Automation Testing using Selenium (Java) I remember this behaviour in old versions of Firefox and Chrome. I not really sure which one but it was reproducible in old version.
This partial basic code (implementated with pageobject) IS WORKING with Firefox 35.0 and Chrome 48.0.2564.109 but NOT IS WORKING with Edge's version I put at the beginning of my comment.
WebElement element = WebDriverExtensions.findElement(context, By.cssSelector("input[name='username'][type='email']"));
element.clear();
element.sendKeys(email);
Front Developers are using AngularJS and are validating user's text input to match with a welformatted email:
I afraid that current Edge version does not support sendkeys with this kind of character, maybe the problem is front on-line validation and Edge has to suits these situations because they are really common.
Best regards
None of the above worked for me with the version 2.52. This worked for me :
EdgeDriver edgeDriver = new EdgeDriver("folder of my edge driver containing MicrosoftWebDriver.exe");
IJavaScriptExecutor js = _edgeDriver as IJavaScriptExecutor;
js.ExecuteScript("document.getElementById('Email').value = 'some#email.com'");
Make sure to replace the ".getElementById('Email')" with what you should use to find your field with javascript and replace the "folder of my edge driver containing MicrosoftWebDriver.exe" with the correct path.
Good luck!

Encoding a line break for Twilio SMS using C#?

I'm using WebApi 2.2 to ramp up on the Twilio API. I have the Twilio C# libraries installed.
I'm using a form to capture a string in my web app, and I send that down to webAPI. I'm wondering how I can leverage the C# libraries to send a message with line breaks.
The example code shows the following:
var msg = twilio.SendMessage("+15084043345", "+15084043345", "Can you believe it's this easy to send an SMS?!");
However, I'm not sure how to include a line break in this message. Should I be inserting anything into this string clientside to represent a linebreak? Any guidance would be awesome.
Twilio Evangelist here.
This is actually super simple:
var msg = twilio.SendMessage("+15084043345", "+15084043345", "Hello.\nCan you believe it's this easy to send an SMS?!");
Will result in:
Hello.
Can you believe it's this easy to send an SMS?!
Just like printing strings to the console, \n, \r\n, and \r can be used to insert a new line. I can't say definitively what is best to use across all handsets, but I have found \n to be pretty reliable. (I can say all three of these work on my iOS 8 device perfectly...)
If you want to show new line in sms like
Account Name : suraj
Age : 24
then here is a code for asp.net VB
Dim value As String = "Account Name :" & "suraj" & vbCrLf & "Age :" & " 24"
it will show new line in SMS not in web page

How to send page cut command to Epson printer

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()

How can I easily represent a raw block of text as a string?

I created a very simple console program that mimics GLaDOS's song from the end of the game, Portal, with the audio and the words all working fine. I ran into a problem when trying to draw the logo at the end.
Is there a way to set a block of text as it is shown into a string so I may write it to the console?
I know that '\n' is a newline but I want to be able to write this out easier.
This is what I have at the moment:
Console.Clear();
TypeText("thank you for participating in the Aperture Science Experiments/nPress any button for delicious cake/n
.,-:;//;:=,
. :H###MM#M#H/.,+%;,
,/X+ +M##M#MM%=,-%HMMM#X/,
-+#MM; $M##MH+-,;XMMMM#MMMM#+-
;#M##M- XM#X;. -+XXXXXHHH#M#M##/.
,%MM##MH ,#%= .---=-=:=,.
=#####MX., -%HX$$%%%:;
=-./#M#M$ .;#MMMM#MM:
X#/ -$MM/ . +MM###M$
,#M#H: :#: . =X#####-
,###MMX, . /H- ;#M#M=
.H####M#+, %MM+..%#$.
/MMMM#MMH/. XM#MH; =;
/%+%$XHH#$= , .H####MX,
.=--------. -%H.,#####MX,
.%MM###HHHXX$$$%+- .:$MMX =M##MM%.
=XMMM#MM#MM#H;,-+HMM#M+ /MMMX=
=%#M#M##$-.=$#MM###M; %M%=
,:+$+-,/H#MMMMMMM#= =,
=++%%%%+/:-.", 90);
Use a verbatim literal string by prefixing with an "#".
You could load a textfile instead and output the contents as text.

Categories