How to access Print Driver settings? - c#

My engraving printer has unique settings for the printer provided by the driver. I know this is common but I'm not sure how it works.
The print driver keeps overriding the DPI to 500, when I want 1000.
I'm using a PrintDocument object in C#. How can I use code to access settings in the print driver? I noticed programs like Access can save print driver settings "per Access form". How do they do it?

for loop below works for identifying device index.
For i = 0 To (Application.Printers.Count - 1) Step 1
Set printCycler = Application.Printers(i)
With printCycler
Msgbox .DeviceName
End With
Next i

Related

Kick Cash Drawer using Control Code

I am working with Epson Thermal printer and Cash Drawer. Cash Drawer is connected with the printer. Reference to http://keyhut.com/popopen.htm, the code to kick cash drawer is 27,112,0,50,250. I tried to send this code to printer but nothing happens. I used POS for .NET and the printer is registed in SetupPos.
Here is my code:
deviceInfo = posExplorer.GetDevice(DeviceType.PosPrinter, strLogicalName);
m_Printer = (PosPrinter)posExplorer.CreateInstance(deviceInfo);
m_Printer.Open();
m_Printer.Claim(1000);
m_Printer.DeviceEnabled = true;
//command = "ESC|p|0|25|251";
command = "\x1B|\x70|\x00|\x19|\xFB";
m_Printer.PrintImmediate(PrinterStation.Receipt, command);
//m_Printer.CutPaper(100);
m_Printer.DeviceEnabled = false;
m_Printer.Release();
m_Printer.Close();
Print text is ok, but send code is not working. What can I do? Thanks.
POS for.NET(UnifiedPOS) specification does not support CashDrawer opening by the PrintNormal()/PrintImmediate() method of POSPrinter device.
Since there is a independent CashDrawer device associated with the POSPrinter device, please open() the corresponding device as a CashDrawer and open the drawer with the OpenDrawer() method.
However, depending on the vendor, there is a possibility of supporting usage like you.
I do not have information on whether EPSON POSPrinter supports such usage or not.
Please ask EPSON or your distributor whether or not you can use such a way.
In addition:
Instead of POS for.NET, there is a way to install and use a device driver as a regular Windows Printer.
Some vendors offer Windows Printer Driver for receipt printers and also support paper cutting and drawer opening functions.
In EPSON, it is provided under the name Advanced Printer Driver.
The questioner seems to have solved the problem using this.
However, this device driver is often used exclusively with POS for.NET/OPOS/JavaPOS, and when printing, it is necessary to use Windows standard printing API.
The third code from open drawer kick code "ESC|p|0|25|251" to send is actually a symbol to control cash drawer 1 or 2, which is using '0' or '1'. The 0 or 1 symbol in the ASCII table is mapped to decimal 48 or 49. So you need to use the Hex x30 or x31 not x00.
Just to add more info, the forth and the fifth code are the time when the signal kick is ON or OFF by sending decimal (value between 0 to 255) * 2ms.
I hope this solve the problem if you still want to use the cash drawer kick code and attach the device to the printer.

Using Redemption RDOContactItem cannot save more than a number of contacts MAPI_E_TOO_BIG

found I'm trying to create contacts into a user's Mailbox programmatically (using Redemption), based on values from a database.
RDOContactItem rci = (RDOContactItem)session.GetDefaultFolder(rdoDefaultFolders.olFolderContacts).Folders["Contacts Subfolder"].Items.Add("IPM.Contact");
...
rci.Save();
As soon as I reach the limit 250, I get the error:
Error in IMsgStore::OpenEntry(Inbox or Root): MAPI_E_TOO_BIG
ulVersion: 0
Error: Your server administrator has limited the number of items you can open simultaneously. Try closing messages you have opened or removing attachments and images from unsent messages you are composing.
Component: Microsoft Exchange Information Store
Read Dmitry Streblechenko's comments on "This is an indication that you have too many open objects. Do you open each and every message in a folder?" suggestions on http://www.microsoft-questions.com/microsoft/Plaform-SDK-Mapi/32731171/mapietoobig.aspx and even tried his suggestion "Do you release all Exchange objects as soon as you are done with them?"
if (rci != null) Marshal.ReleaseComObject(rci);
even casting to IDisposable to able to dispose it, but it didn't work.
I haven't find a way to close a contact item after being saved.
Increasing the number of items that can be opened simultaneously on the server side is not a happy option either.
How to solve this?
You are using multiple dot notation (5 if I am counting correctly), and that causes the compiler to create implicit variables that you cannot explicitly release. Try the following. You can also try to call GC.Collect() every once in a while, but that would be a sledgehammer of a solution...
RDOFolder contacts = session.GetDefaultFolder(rdoDefaultFolders.olFolderContacts);
RDOFolders folders = contacts.Folders;
RDOFolder subfolder = folders["Contacts Subfolder"];
RDOItems items = subfolder.Items;
RDOMail msg = items.Add("IPM.Contact");
RDOContactItem rci = (RDOContactItem)msg;
...
rci.Save();
Marshal.ReleaseComObject(rci);
Marshal.ReleaseComObject(msg);
Marshal.ReleaseComObject(items);
Marshal.ReleaseComObject(subfolder);
Marshal.ReleaseComObject(folders);
Marshal.ReleaseComObject(contacts);

How to programmatically print on Letterhead, Cardstock, Pre-printed paper in .NET

I am attempting to print from a WCF service using the System.Drawing.Printing library. The problem is that I am attempting to choose a paper type (or media type) of Letterhead, Cardstock, or Pre-printed paper which does not appear to be available in this library.
System.Drawing.Printing has a PageSettings class, but I can only set the PaperSize and there is no PaperSize for Letterhead, Cardstock, Pre-printed, etc.
https://msdn.microsoft.com/en-us/library/System.Drawing.Printing.PageSettings(v=vs.110).aspx
Also the PaperSource class from PrinterSettings.PaperSources does not contain any information about what kind of paper is in each tray.
Does anyone have a recommendation how to ensure the print job I send has the correct settings so that the printer will know which tray to print from?
There MUST be a way to do this. For example, I can select Letterhead when printing from Word or Excel, but only when I go to Printer Properties. Why can I not do this programmatically in .NET? Is this a managed code limitation? Do I need to access the printer driver?
Even System.Printing does not have these options available. Also MSDN states:
Caution: Classes within the System.Printing namespace are not supported
for use within a Windows service or ASP.NET application or service.
Attempting to use these classes from within one of these application
types may produce unexpected problems, such as diminished service
performance and run-time exceptions.
The only other option I have available is to have the user manually set up each printer with the kind of paper in each tray in a database with some user interface. Then I would just set the tray to print from. I would like to avoid this if possible.
UPDATE DEC 14, 2015
The printer manufacturer is willing to give a paid solution but that is not feasible for the project at this time.
Rough code solution is:
private PrintJobStatusEnum SendToPrinter(PrintDocumentModel printJob, out List<string> errors)
{
errors = new List<string>();
// The print job includes the printer and page settings
var printerSettings = new PrinterSettings
{
PrinterName = "MyPrinterName",
Duplex = printJob.IsDuplex ? Duplex.Vertical : Duplex.Simplex
};
// Set the paper size
var paperKind = PaperKind.Letter;
// Find the paper size in the available sizes on the printer
var paperSizes = printerSettings.PaperSizes.Cast<PaperSize>().AsQueryable();
var paperSize = paperSizes.FirstOrDefault(p => p.Kind == paperKind);
// Set the paper source (tray)
var paperSources = printerSettings.PaperSources.Cast<PaperSource>().AsQueryable();
// The SourceName is different for many printers.
// Double-check yours through PrinterSettings.PaperSources
var paperSource = paperSources.FirstOrDefault(s => s.SourceName == "Cassette 1");
if (paperSource == null)
{
paperSource = paperSources.FirstOrDefault(s => s.Kind == PaperSourceKind.AutomaticFeed);
}
// Set up the page
var pageSettings = new PageSettings
{
Landscape = printJob.PaperOrientationLookUpId == MyConstants.PaperOrientationLandscape,
Margins = new Margins(0, 0, 0, 0), // Not sure if margins are needed
PaperSize = paperSize ?? new PaperSize("Letter", 850, 1100),
Color = printJob.IsColor,
PaperSource = paperSource,
PrinterSettings = printerSettings
};
// Send document, printer settings and page settings to print handler
List<string> printErrors;
var result = _pdfPrintHandler.Print(printerSettings, pageSettings, printJob, out printErrors);
errors.AddRange(printErrors);
return result;
}
How this used to work and probably still does with .NET is all these features are specific to a printers driver. They are not exposed as callable APIs. What paper size and type etc. are user configurable at run-time. The driver will change what precise method it uses to stick the ink to the paper and it is none of your business.
The driver will however tell you how big the paper is your printing to and you can rework the output accordingly. You can also choose to programmatically flip the rendering yourself to make portrait and landscape.
You can save and load printer configs "Page Setups". So you could get the user to configure different "Page Setups" with different tray selections and switch between them when you print.
https://social.msdn.microsoft.com/Forums/vstudio/en-US/0e1194ee-d71b-45b4-b4c2-5b626a100d30/windows-print-spooler-api-and-paper-tray-selection?forum=netfxbcl

Why would a Zebra QLn220 Printer ignore the first couple of commands sent to it after sending it a command to update some settings?

I am sending commands to a Zebra QLn220 for it to print labels (naturally). I also have code, though, that assigns values to certain printer settings, such as:
const string quote = "\"";
string keepPrinterOn = string.Format("! U1 setvar {0}power.dtr_power_off{0} {0}off{0}", quote);
string advanceToBlackBar = string.Format("! U1 setvar {0}media.sense_mode{0} {0}bar{0}", quote);
string advanceToGap = string.Format("! U1 setvar {0}media.sense_mode{0} {0}gap{0}", quote);
PrintUtils.SendCommandToPrinter(keepPrinterOn);
if (radbtnBar.Checked)
{
PrintUtils.SendCommandToPrinter(advanceToBlackBar);
}
else if (radbtnGap.Checked)
{
PrintUtils.SendCommandToPrinter(advanceToGap);
}
This works - after running that code with radbtnBar checked, those settings are now (as seen via running "! U1 getvar "allcv"" in the Zebra Setup Utilities app):
power.dtr_power_off : off , Choices: on,off
media.sense_mode : bar , Choices: bar,gap
The problem is that after setting those values via the code above, and then attempting to print labels (after a lapse of at least 20 seconds, and have tested up to more than a minute), the first couple of attempts to print a label silently fail (there is no err msg, it is just that no printing takes place). On the third attempt, the label prints. Why would setting these vals cause the printer to temporarily "go deaf," and is there anything I can do to shake it back to wakefulness following the programmatic application of those settings so that it will print immediately?
Once the QLn220 finally regains responsiveness, it continues to print immediately on subsequent executions of the app with no delays; it's only after sending those commands ("power.dtr_power_off" and "media.sense_mode") that the printer is knocked out of its orbit for a season. A real zebra would never be as stubborn as a mule like this.
UPDATE
Banno's idea did the trick, apparently (appending crlfs ("\r\n")) to the commands to set the printer vars.
So it seems that what was happening was something like this:
Command 1 was sent to the printer to set a val (with no crlf).
Command 2 was sent to the printer to set another val (also with no crlf)
A label was then attempted to be printed; it didn't print. Seeing that it did have a crlf, though, the printer seemed to say, "Oh, you finally gave me one of the crlfs you owe me! But you're not getting off that easy - you still owe me one!"
A second attempt to print a label caused the printer to say, in effect, "Okay, then, you've paid your crlf debt; from now on, I will listen to the commands you send (as long as you terminate them with the crlf I so ravenously crave)."
UPDATE 2
Sometimes it still doesn't work (inconsistent behavior); I found that I had to "poke it" to get it to quit its somnambulism; see What Zebra QLn220 settings do I need to set (and to what value[s]) to get a setting to "stick"?
append "\r\n\" to each command

how to print to Printronix Printer?

Does someone has already printed to a printronix printer (serie t5000r) using .NET (visual basic or C#) ?
We already have the file (txt) with the code to generate the label until I know the code it's PGL.
What've done was to use file.copy() to send the file to the LPT1 port (we use this method with Zebra printers and it works fine) but the printer print plain text instead of the label with it's format (barcode, titles, etc).
Any idea?
Here is the label code, thank you in advance:
^CONFIG
SFCC;94
END
^CONFIG
LEFT MARGIN;5
END
^PAPER;LENGTH 80
^PAPER;WIDTH 60
^PAPER;PORTRAIT
^CREATE;ds-label
FONT;FACE 92250
ALPHA
AF2;100;DARK;POINT;8;6;45;40
AF4;100;DARK;POINT;13;6;45;40
AF60;100;DARK;POINT;18;6;45;40
AF61;100;POINT;22;6;30;30
STOP
FONT;FACE 93779
ALPHA
POINT;5;6;10;0;Some data 1:
POINT;10;6;10;0;Some data 2:
POINT;15;6;10;0;Delivery Address:
POINT;20;6;10;0;NSC Name:
POINT;24;6;10;0;CODE barcode:
POINT;34;6;10;0;CODE number:
AF63;17;DARK;POINT;37;6;46;23
POINT;39;6;10;0;PID:
AF64;26;DARK;POINT;41;6;28;14
POINT;43;6;10;0;Label Code:
AF65;8;POINT;44;6;15;0
POINT;46;6;10;0;Date:
AF66;10;POINT;47;6;15;0
STOP
BARCODE
C3/9;X1;H10;BF10;17;26;8
STOP
END
^EXECUTE;ds-label
^AF2;ALVSBORGSH. YYY-XXX
^AF4;IMMINGHAM PORT IMPORTS
^AF60;THE CITY
^AF61;Great Britain
^BF10;11111111111111111
^AF63;11111111111111111
^AF64;AAAAAAY1T1MMA7290B11111111
^AF65;0067PXXX
^AF66;2008-10-15
^NORMAL
^CONFIG
RESET
END
I guess your text get intercepted somewhere on the way and rendered to a page instead of sent directly to the printer port. I found this article - How to send raw data to a printer by using Visual C# .NET - that may be of help.

Categories

Resources