Sending PDF to Thermal Printer (Zebra) using c# - c#

I am trying to send a PDF to a thermal printer using c#. I have looked at the RawPrinterHelper class here http://support.microsoft.com/kb/322091 but the SendFileToPrinter is not printing the file.
There is no error and the file appears to be printing from the print queue but nothing happens.
The printer works fine as I have been able to print other items on it.
Does anyone know how I can send a PDF to print or how I can possibly use the SendFileToPrinter to work for me.
I am working on Windows 7.
Here is a sample of the code I am using to call the SendFileToPrinter method.
try
{
RawPrinterHelper.SendFileToPrinter(PrinterName,#"C:\test.pdf");
}
catch (Exception ex)
{
Console.WriteLine(" EXCEPTION: {0}", ex.Message);
}
Update:
Ok, maybe I spoke too soon. I am able to print the PDF to the thermal printer but the issue now is that this is taking a couple of seconds to print and I am looking for something that is "quick". The reason it is slow is that Adobe needs to open up first.
Anyone have any ideas on how to get around this?

Ok, actaully got it sorted.
I was able to do the following and it works perfectly.
string tempFile = #"C:\test.pdf";
try
{
ProcessStartInfo gsProcessInfo;
Process gsProcess;
string printerName = PrinterName;
gsProcessInfo = new ProcessStartInfo();
gsProcessInfo.Verb = "PrintTo";
gsProcessInfo.WindowStyle = ProcessWindowStyle.Hidden;
gsProcessInfo.FileName = tempFile;
gsProcessInfo.Arguments = "\"" + printerName + "\"";
gsProcess = Process.Start(gsProcessInfo);
if (gsProcess.HasExited == false)
{
gsProcess.Kill();
}
gsProcess.EnableRaisingEvents = true;
gsProcess.Close();
}
catch (Exception)
{
}
#DavidCrowell, thats for the assistance.
Noel.

Related

Zebra Printer Calibration

I'm using Zebra printer model ZQ520 and connecting to it through application in C#.
string zpl = "^XA^FO20,20^A0N,25,25^FDThis is a ZPL test.^FS^XZ";
try
{
connection.Open();
string setLang = "! U1 setvar \"device.languages\" \"zpl\"\r\n";
string calibrate = "~jc^xa^jus^xz\r\n";
connection.Write(Encoding.UTF8.GetBytes(setLang));
connection.Write(Encoding.UTF8.GetBytes(calibrate));
connection.Write(Encoding.UTF8.GetBytes(zpl));
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine("Exception:" + e.Message);
}
The issue is the printer is printing out an excessive amount of paper. It doesn't print "This is a ZPL test." until I press the line feed button on the printer, and then it printer more excess paper after the desired message.
Any idea what issue might be?
Have you checked the ^LL (Label Length) command. Look it up in your Zebra Programming Language guide.
I also know when I was doing Zebra (and also Intermec), the device itself had machine settings / display using buttons and arrows to change such default settings as page sizes, if thermal, what burn strength 0-30, etc., so you did not have to invoke those on every label submit.
I was also communicating directly with serial port using USB to RS232 connector cable, but it has been a while.
You may try to use the following code to communicate with the printer:
using (var tcpClient = new TcpClient())
{
try
{
var ipAddress = "127.0.0.1";
var printerPort = 9001;
tcpClient.Connect(ipAddress, printerPort);
using (var tcpClientStream = new StreamWriter(tcpClient.GetStream()))
{
var deviceLang = "! U1 setvar \"device.languages\" \"zpl\"\r\n");
tcpClientStream.Write(deviceLang );
tcpClientStream.Flush();
var calibrate = "~jc^xa^jus^xz";
tcpClientStream.Write(calibrate);
tcpClientStream.Flush();
Thread.Sleep(500);
string zpl = "^XA^FO20,20^A0N,25,25^FDThis is a ZPL test.^FS^XZ";
// with ^LL: string zpl = "^XA^LL400^FO20,20^A0N,25,25^FDThis is a ZPL test.^FS^XZ";
tcpClientStream.Write(zpl);
tcpClientStream.Flush();
tcpClientStream.Close();
}
tcpClient.Close();
}
catch (Exception ex)
{
Logger.Error(ex); // replace with your own logger or console
}
}
This should print the expected text immediately. Other than that, for continuous media (i.e. no gaps). I'm not familiar with this particular model but according to this:
https://supportcommunity.zebra.com/s/article/Calibrating-Zebra-QLn-Series-Mobile-Printers?language=en_US
You need to send the following command: ! U1 setvar "media.type" "journal" then set the label length somehow, for example ^LL400.
Also you may try to comment the deviceLang and calibrate commands, not 100% sure those are really required (on the ZT610 they're definitely not, as you can calibrate the printer using buttons).

Network printers ignoring number of copies sent programatically

The setup - a local Windows 10 PC has multiple network printers installed. A GUI C# WinForm application (.NET) is constantly running in the background, and occasionally downloads a PDF file from a predefined URL (read from an *.ini file).
The problem occurs when the said PDF file is printed. Instead of accepting the number of copies sent from the application, the printer keeps printing just one copy of the file.
This is the relevant part of my code:
string webPrinter = "HP LaserJet PCL 6"; // is set in another part of the code
string iniFilePrinter = "hp LaserJet 1320 PCL 5"; // is set in another part of the code - read from the ini file
string dirName = "C:\\mydir";
string newDocName = "mydoc.pdf";
short numCopies = 1;
if(event1 == "event1") { // taken from another part of the code
numCopies = webNumCopies; // taken from another part of the code
} else if(event2 == "event2") {
numCopies = iniNumCopies; // taken from another part of the code - read from the ini file
}
var path = dirName + "\\" + newDocName;
try
{
using (var document = PdfiumViewer.PdfDocument.Load(path))
{
using (var printDocument = document.CreatePrintDocument())
{
System.Drawing.Printing.PrinterSettings settings = new System.Drawing.Printing.PrinterSettings();
string defaultPrinterName = settings.PrinterName;
printDocument.DocumentName = newDocName;
printDocument.PrinterSettings.PrintFileName = newDocName;
printDocument.PrinterSettings.Copies = numCopies;
printDocument.PrintController = new System.Drawing.Printing.StandardPrintController();
printDocument.PrinterSettings.PrinterName = webPrinter;
MessageBox.Show("Before: " + printDocument.PrinterSettings.Copies.ToString() + " --- " + newDocName);
if (!printDocument.PrinterSettings.IsValid)
{
printDocument.PrinterSettings.PrinterName = iniFilePrinter;
if(!printDocument.PrinterSettings.IsValid)
{
printDocument.PrinterSettings.PrinterName = defaultPrinterName;
}
}
MessageBox.Show("After: " + printDocument.PrinterSettings.Copies.ToString() + " --- " + newDocName);
printDocument.Print();
}
}
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
The exception has never been triggered, and the print succeeds on every single try. Changing the number of copies within if/else also happens when the conditions are met, and the MessageBox.Show() parts of the code do show the expected number of copies (2,3,7, anything but 1, when it's not supposed to be 1) immediatelly before invoking printDocument.Print().
I've also tried printing unrelated documents from various other programs (MS Word, various custom applications, PDF readers and the like), and the number of copies has always been 1. However, software like Google Chrome or FireFox manage to get things printed in the specified number of copies.
I was thinking that there might be something about the printer's setting which makes it ignore the number of copies sent. Based on that assumption, I've checked the settings of all of the printers, and have found that the number of copies is actually set to 1.
If that is indeed the cause of my problem, how can I bypass that setting (without actually changing it), the way that Google Chrome and Firefox seem to be able to do it? I know that I could probably change that limit programmatically (set it to my number of copies, and then change it back to the original value, once the printing has been completed), but that doesn't seem like the proper way of doing it.
EDIT
I've expanded my code by including a print dialog, like this:
PrintDialog printDlg = new PrintDialog();
printDlg.Document = printDocument;
printDlg.AllowSelection = true;
printDlg.AllowSomePages = true;
if (printDlg.ShowDialog() == DialogResult.OK)
{
printDocument.Print();
}
Still, the results are the same - even when the user changes the number of copies within the print dialog, the printer ignores them. The same code was tested on another (local) printer, connected to an unrelated Windows 10 PC, and there the number of copies from the dialog was not ignored.
I've also noticed that the print dialog from my application, and that from notepad.exe are different (image below). Is there a way for me to call up the same print dialog notepad.exe uses? The reason I'd like to do this, is because that one gets the job done (xy number of copies in the print dialog, xy number of copies printed).

Camera server died! Error 100 when starting recording

NOTICE: I'm Using Monodroid, expect C# code.
I'm facing this error when the _recorder.Start() is called.
CODE:
private void IniciarGrabacion()
{
try
{
CamcorderProfile camProfile = CamcordeProfile.Get(CamcorderQuality.High);
String outputFile = "/sdcard/trompiz.mp4";
_camera.Unlock ();
_recorder = new MediaRecorder();
_recorder.SetCamera(_camera);
_recorder.SetAudioSource(AudioSource.Default);
_recorder.SetVideoSource(VideoSource.Camera);
_recorder.SetProfile(camProfile);
_recorder.SetOutputFile(outputFile);
_recorder.SetPreviewDisplay(_preview.Holder.Surface);
_recorder.Prepare();
_recorder.Start(); // HERE IS WHERE THE ERROR APPEARS
}
catch(Exception ex)
{
string error = "Error starting Recording: " + ex.Message;
Log.Debug("ERROR",error);
Toast.MakeText(Application, error, ToastLength.Long).Show();
}
}
The outputFile is hardcoded because i'm still testing.
I can confirm that exists because it gets created.
I just figured the problem.
It wasn't on how the camera was handled.
It was the Profile setting.
CamcorderProfile camProfile = CamcordeProfile.Get(CamcorderQuality.High);
Might be a Device bug, but I cant set it to high. To make it work, I changed it to LOW.
CamcorderProfile camProfile = CamcordeProfile.Get(CamcorderQuality.Low);
I have a Zenithink C93 Z283 (H6_2f)
I hope this helps anyone else fighting with this...
Now I have to see how to record on High quality. I know I can because the native camera app records in high....

Convert proc.HasExited from C#.Net to Java

I have a C#.Net console app code that transfers files between linux and windows ftp servers.
The code's behavior is that I automatically open a console to display status of the file transfer. While transferring files to and from the windows server, I need to display an indicator that the file transfer is on-going (using symbols that look like they are moving or turning) . These symbols are as follows : "|" --> "/" --> "-" --> "\" --> "|"
There had been no problem displaying the said "indicator/symbols" in C#.Net using the following codes :
ProcessStartInfo PSI = new ProcessStartInfo("CMD.exe", "/C [here is the call to psftp / ftp scripts]");
String SymbolChar = "|";
Process proc = Process.Start(PSI);
while (true)
{
Thread.sleep(20);
if (proc.HasExited)
{
Console.WriteLine("\b-> Done\n");
break;
}
else
{
SymbolChar = NextChar(SymbolChar);
Console.Write("\b{0}", SymbolChar);
}
}
StreamReader srError = proc.StandardError;
StreamReader srOutput = proc.StandardOutput;
//method used to animate status during process
private static String NextChar(String sCurrentChar)
{
String sTempChar = "";
if (sCurrentChar.equals("|")) {
sTempChar = "/";
}
else if (sCurrentChar.equals("/")) {
sTempChar = "-";
}
else if (sCurrentChar.equals("-")) {
sTempChar = "\\";
}
else if (sCurrentChar.equals("-")) {
sTempChar = "\\";
}
else if (sCurrentChar.equals("\\")) {
sTempChar = "|";
}
return sTempChar;
}
My problem started when I converted the said codes into java using the following :
String sParam = "bash " + [here is the call to psftp / ftp scripts];
String cmd[] = {"/bin/bash","-c",sParam};
Process proc = Runtime.getRuntime().exec(cmd);
Above code is perfectly working.
Problem is I don't know how to display the "animated" characters anymore.
I suddenly don't know (and I badly need help on) how to convert this :
Process proc = Process.Start(PSI);
while (true)
{
Thread.sleep(20);
if (proc.HasExited)
{
Console.WriteLine("\b-> Done\n");
break;
}
else
{
SymbolChar = NextChar(SymbolChar);
Console.Write("\b{0}", SymbolChar);
}
}
Do you have any idea as to what I can use for the line "if (proc.HasExited)" in java so that I could move forward?
Sorry for the long explanation.
I really, really need help.
Thank you very much in advance!
You could use 'Process.exitValue()' and catch the Exception (it will throw an Exception if the process is not done yet). If the value is 0 the process exited normally. However this is rather ugly IMHO.
The only 'proper' way I know in Java to wait for a process to finish is to have the current Thread block until the Process is done with 'Process.waitFor()'.
This would however require a different thread to display your progress animation since your current thread is blocked and waiting for the Process to finish.

C# Prevent Adobe Reader Window from coming up when trying to print a document

For reasons I can't get into right now, I need to prevent the Adobe Reader window from opening up when I try to print a document. The developer that was working on this before me has the following flags set, although I'm not really sure what they're for -
if (RegistryManager.GetAcrobatVersion() >= 9.0f)
printerArg = "\"" + printerName + "\"";
else
printerArg = printerName;
Process myProc = new Process();
myProc.StartInfo.FileName = fileName;
myProc.StartInfo.Verb = "printto";
myProc.StartInfo.UseShellExecute = true;
myProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
myProc.StartInfo.CreateNoWindow = true;
myProc.StartInfo.Arguments = "\"" + printerName + "\"";
bool result = myProc.Start();
if (myProc.WaitForInputIdle())
{
if (!myProc.HasExited)
{
myProc.WaitForExit(Convert.ToInt32(5000));
myProc.Kill();
}
}
myProc.Close();
Any help is much appreciated!
Thanks,
Teja.
While I can't answer your question specifically, I found that I couldn't do this as Adobe changed Reader I think at version 9 or 10 so that you couldn't supress the print dialog, and the window itself kept coming up anyway, and since my users all had different versions of Reader installed I couldn't get anything consistently working. If you want to try anyway have a look at Reader's API - you need to add a reference to the correct COM library and go from there. Painful.
I ended up dropping Adobe completely by running the PDF through GhostScript. Following is the helper class I created to do the job. gsExePath should be something like C:\Program Files\gs\gs8.71\bin\gswin32c.exe.
public class GSInterface
{
public string GhostScriptExePath { get; private set; }
public GSInterface(string gsExePath)
{
this.GhostScriptExePath = gsExePath;
}
public virtual void CallGhostScript(string[] args)
{
var p = new Process();
p.StartInfo.FileName = this.GhostScriptExePath;
p.StartInfo.Arguments = string.Join(" ", args);
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.Start();
p.WaitForExit();
}
public void Print(string filename, string printerName)
{
this.CallGhostScript(new string[] {
"-q",
"-sDEVICE=mswinpr2",
"-sPAPERSIZE=a4",
"-dNOPAUSE",
"-dNoCancel",
"-dBATCH",
"-dDuplex",
string.Format(#"-sOutputFile=""\\spool\{0}""", printerName),
string.Format(#"""{0}""", filename)
});
}
}
The following should print to the Windows default printer:
var printerName = new System.Drawing.Printing.PrinterSettings().PrinterName;
var gs = new GSInterface(gsExePath);
gs.Print(filename, printername);
This may apply only to the computers where I work, or, more broadly, to this version of Adobe (10) on PCs with Windows 7 installed, but I was able to suppress the opening of Acrobat (Pro) each time I printed to .pdf in any other application by doing the following:
Control Panel > (Devices and) Printers > Double click 'Adobe PDF'> Click 'Printer' > 'Printing Preferences' > Uncheck "View Adobe PDF Results" in the 'Adobe PDF Settings' Tab.
Maybe it is helpful for you to use the "/n" parameter of Adobe Reader.
At least your program keeps the focus. But one instance of the reader stays open.
AcroRd32.exe /n /t ...
See: Questions 619158
Regarding the solution Adam proposed (switching off the View Adobe PDF Results from control panel) and Serge Belov commented (on how to do it programmatically), in the registry this change affects the ViewPrintOutput value at 4 positions:
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\Adobe PDF\PrinterDriverData
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Print\Printers\Adobe PDF\PrinterDriverData
Computer\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Print\Printers\Adobe PDF\PrinterDriverData
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Printers\Adobe PDF\PrinterDriverData
However, if you change it from the registry, it doesn't affect the adobe pdf's behaviour, it still shows the resulting pdf after printing
This might be helpful, though
https://groups.google.com/g/microsoft.public.access.reports/c/LWphtEVp6UI

Categories

Resources