C# PrintDocument PaperSource not applied on some Printers - c#

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

Related

Ways to Count a Printer With a Built in Scanner as a Scanner for WIA

I am currently working with some OMR software that will take and scan sheets from a scanner, and then write their information to a text file. For getting available local scanners, I am using WIA; to get these scanners, I would use some bit of code like
public List<ScannerInfo> GetWiaDevices()
{
WIA.DeviceManager mgr = new WIA.DeviceManager();
List<ScannerInfo> retVal = new List<ScannerInfo>();
foreach (WIA.DeviceInfo info in mgr.DeviceInfos)
{
if (info.Type == WIA.WiaDeviceType.ScannerDeviceType)
{
foreach (WIA.Property p in info.Properties)
{
if (p.Name == "Name")
retVal.Add(new ScannerInfo(((WIA.IProperty)p).get_Value().ToString(), info.DeviceID));
}
}
}
return retVal;
}
Now, I am working with something that is technically a printer (and that Windows reads as a printer) -- the Konica Minolta Bizhub 282, I believe. Unfortunately, if (info.Type == WIA.WiaDeviceType.ScannerDeviceType) doesn't recognize printers with built in scanners as scanners, so when I run this code checking for local scanners, the printer doesn't show up.
Is there a way to make printers with built-in scanners show up on the list, and furthermore, to make them usable as scanners in C#? Thanks for your time!
It doesn't look like this printer has a scanner that will show up as a twain or WIA source.
There certainly are no drivers on the Minolta site for it (only PCLx and PostScript Print Drivers).
The way this scanner works is to use a SMB network share setup by your IT admin. The printer will dump scanned documents there after it is configured properly.
You can read about it here .
If I somehow missed something.. (I don't think I did), ALL of the manuals for that printer are here

.NET Printing. Always Use Default Preferences

I have a service which prints. Up until now the service has been printing using the WPF System.Windows.Controls.PrintDialog.PrintDocument method however due to various issues (performance, windows update bugs, 32 bit service on 64bit system issues etc) I am converting to use the traditional System.Drawing.Printing.PrintDocument method.
As this is running as a service I want this to always print using the default printer preferences (which include things like media settings and print speed for industrial label printer such as the Intermec/Honewell PM43)
Previously I had done this using PrintDialog.PrintTicket = PrintQueue.DefaultPrintTicket.Clone
However I cannot find the equivalent method in System.Drawing.Printing.PrintDocument and the service is not picking up the default printer preferences as set in the printer properties (specifically Print Speed in this case)
So what is the equivalent of PrintDialog.PrintTicket = PrintQueue.DefaultPrintTicket.Clone in System.Drawing.Printing.PrintDocument?
The following question helped me find an answer
Can't change DEVMODE of a printer
//Get the registry key containing the printer settings
var regKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System\\CurrentControlSet\\Control\\Print\\Printers\\" + PrinterName);
if (regKey != null)
{
//Get the value of the default printer preferences
var defaultDevMode = (byte[])regKey.GetValue("Default DevMode");
//Create a handle and populate
var pDevMode = Marshal.AllocHGlobal(defaultDevMode.Length);
Marshal.Copy(defaultDevMode, 0, pDevMode, defaultDevMode.Length);
//Set the printer preferences
pd.PrinterSettings.SetHdevmode(pDevMode);
//Clean up
Marshal.FreeHGlobal(pDevMode);
}

Page Width does not match Paper Size in Windows Print Dialog

I am trying to print to an unusual printer (BIXOLON SPP-R200III) from a C# WPF application. The width of this printer's paper roll is 58mm, as measured with a ruler and as shown in the Windows Print Dialog box:
However, when I try to connect to this printer and interrogate its capabilities via the System.Printing APIs in the .NET Framework, I get a different paper width.
The following code enumerates print queues and finds the correct one:
const string printQueueName = #"BIXOLON SPP-R200III";
PrintServer printServer = new PrintServer();
PrintQueue printQueue = null;
PrintQueueCollection printQueues = printServer.GetPrintQueues();
foreach (PrintQueue queue in printQueues)
{
if (String.Equals(queue.FullName, printQueueName, StringComparison.CurrentCultureIgnoreCase))
{
printQueue = queue;
break;
}
}
This code interrogates its capabilities:
PrintTicket defaultTicket = printQueue.DefaultPrintTicket;
PrintCapabilities printCapabilities = printQueue.GetPrintCapabilities(defaultTicket);
double pageWidth = (printCapabilities.OrientedPageMediaWidth.Value / 96.0) * 25.4;
But the result, pageWidth is 48.047 and not 58mm as expected!(PrintCapabilities.OrientedPageMediaWidth is 181.59496062992128.)
I also tried looking at the default print-ticket structure itself but printQueue.DefaultPrintTicket.PageMediaSize.Width has the same value of 181.59496062992128.
Finally, I tried to use the System.Windows.Controls.PrintDialog with the following code:
PrintDialog printDialog = new PrintDialog();
printDialog.PrintQueue = printQueue;
printDialog.ShowDialog();
double pageWidth = (printDialog.PrintTicket.PageMediaSize.Width.Value / 96.0) * 25.4;
And I got the same result.
Why is this? Why do these widths not match? Am I converting from dots to millimetres incorrectly? Am I completely misunderstanding printer capabilities?
What is the right way to find the paper size supported by a printer, like it is shown in the screenshot at the top of this question?
Because there is so called "imageble area", which is always smaller than the physical dimensions of the sheet.
Probably, your printer cannot print at the very edge of the sheet.
You can make sure by inspecting the PrintCapabilities.PageBorderlessCapability Property.
See this link: https://msdn.microsoft.com/en-us/library/system.printing.printcapabilities.pageborderlesscapability(v=vs.110).aspx
Most laser and inkjet printers do not support borderless printing. They must allow an unprinted margin to prevent toner from getting on the parts of the printer that move the paper. Many photographic printers, however, do support borderless printing.
If the printer does not support borderless printing, the collection is empty.

Enforce program settings

I have made a small c# winforms program which among other stuff, prints barcodes. On some client machines where it operates, some other software for printing barcodes overrides my settings for printing the barcode and it resizes just the barcode.
If I change the code just for that machine, it either repositions the image (makes it smaller as well), or stretches it so wide that it cuts off one third of it. Currently I am only using the printing settings to set the margins to 0 and set the paper mode to landscape in the print dialog, and the image size is fixed in the printing process(I used constants). Below is the code for when the user clicks the print button, and also two constants defined outside of it.
const int barcodeX = 570;
const int barcodeY = 135;
private void Print_Click(object sender, EventArgs e)
{
DocPrint.DocumentName = "Document";
elements = 0;
PrintDialog.Document = DocumentDrucker;
DocPrint.DefaultPageSettings.Landscape = true;
DocPrint.DefaultPageSettings.Margins.Top = 0;
DocPrint.DefaultPageSettings.Margins.Left = 0;
DocPrint.DefaultPageSettings.Margins.Right = 0;
DocPrint.DefaultPageSettings.Margins.Bottom = 0;
//DocumentDrucker.OriginAtMargins = false;
if (PrintDialog.ShowDialog() == DialogResult.OK)
DocPrint.Print();
}
Also the lines to encode and print the barcode in the printing process. The barcodePoint is where the barcode is positioned, on the paper.
b.Encode(TYPE.CODE128A, "SBD" + currentItem.Text.Substring(0, 3) + currentItem.Text.Substring(4), Color.Black, Color.Transparent, barcodeX, barcodeY);
graphic.DrawImage(b.EncodedImage, barcodePoint);
The program runs fine under any other circumstances, so I have identified the problem, I just do not know how to go around the other software's settings. I have already reinstalled the drivers for the printer (no success), as well logged in as a different user on the same computer, and that made my program work. So it has something to do with the software installed on it, I just don't know what.
At first I thought it was a problem with the drivers and the OS, but I tried it on other computers and it worked fine as well. The problem persists just on the computers with the software.
Is there any way to make my program force it's printing settings for the barcode image, since the software installed on the machines always uses it's own settings? Or to make sure that the settings in my code will not be changed?
Uninstalling the software is not an option, as it is used for other processes.
EDIT: I have run the program from both my user logon (no software) and the target machine user (both on the same machine). The settings were identical in both cases, the only thing different was that on the target machine, the software was installed. What are some ways to make sure that my settings are enforced, instead of an X program overwriting them?

C# - Windows Mobile - Pairing with Zebra RW 420

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

Categories