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

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

Related

Adding a new Language to SpeechSynthesizer

So I'am trying to add a new language, spesifically norwegian, to SpeechSynthesizer, but it doesn't seem to get installed.
Found this:
Add another voice into .NET Speech
(But here the problem is that Czech isn't supported)
I have installed the norwegian pack from here:
http://www.microsoft.com/en-us/download/details.aspx?id=27224
In my code I use this to check if it is installed:
foreach (var voice in speaker.GetInstalledVoices())
{
Console.WriteLine(voice.VoiceInfo.Description);
}
But it only outputs:
Microsoft Zira Desktop - English (United States)
Have checked the text-to-Speech tool were this is also the only option.
Have also tried to log off/log on and restart the computer.
Anyone know how to fix this?
You may need to add a Speech Language to Windows 10 and set your Locale, Country, Windows display language and Speech language so they are all aligned with one of Cortana's supported locale configurations.
To confirm the settings are set correctly:
Open Settings. Select Time& language, and then Region & Language.
Check the Language (set as default) setting for your Windows display language. If your desired language is not available, add your desired language:
Click Add Language.
Select your desired language from the list.
Select the desired locale, which is the language/country combination.
Click on the newly selected locale and select Options.
Under Download language pack, click Download.
Under Speech, click Download.
After the downloads are complete (this could take several minutes), return to the Time & Language settings.
Click on your new language and select Set as Default.
NOTE: IF you changed languages, you must sign out of your account and back in for the new setting to take effect.
Check the Country or region setting. Make sure the country selected corresponds with the Windows display language set in the Language setting.
Return to Settings and Time & language, and then select Speech. Check the Speech language setting, and make sure it’s aligned with the previous settings.
After you have correctly done the above, your language should appear in the SpeechSynthesizer.AllVoices collection. You should then be able to assign this voice to your SpeechSynthesizer instance's Voice property:
private async void SpeakText(MediaElement audioPlayer, string TTS)
{
SpeechSynthesizer ttssynthesizer = new SpeechSynthesizer();
//Set the Voice/Speaker to Spanish
using (var speaker = new SpeechSynthesizer())
{
speaker.Voice = (SpeechSynthesizer.AllVoices.First(x => x.Gender == VoiceGender.Female && x.Language.Contains("ES")) );
ttssynthesizer.Voice = speaker.Voice;
}
SpeechSynthesisStream ttsStream = await ttssynthesizer.SynthesizeTextToStreamAsync(TTS);
audioPlayer.SetSource(ttsStream, "");
}
http://answers.microsoft.com/en-us/windows/forum/windows_10-other_settings/speech-language-in-windows-10-home/3f04bc02-9953-40b1-951c-c1d262fc3f63?auth=1

Getting the changed printer preferences for a printer from controlpanel through code

I have to print a document to any of the installed printers from the wpf application. User can select the printer and click on the print button. I am able to print the document with the selected printer. But if i change the printer preferences from the control panel ex: Pages Per sheet, color etc, I am not able to get those changed printer preferences for printing the document. I have used both the printQueue.DefaultPrintTicket and printQueue.UserPrintTicket in the code but both are giving the default settings only.
How can we always get the changed printerpreferences for a printer from control panel instead of default settings through the code and apply those printer preferences while printing?
This seems to be caused by a bug in the WPF printing classes, see:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/6ebf6d61-a356-41c3-a444-a24fb38416fe/printticket-not-reflecting-printing-preferences?forum=wpf
As a workaround you can use the PrintDialog (without showing it) to get the correct settings on the default printer, unfortunately you need to temporary change the windows default printer in order to get settings for other printers than the default one.
I wrote this method, seems to be working fine.
/// <summary>
/// Get current settings (encapsulated in an PrintTicket) for a specific printer.
/// </summary>
private static PrintTicket GetPrinterSettings(PrintQueue printer)
{
try
{
// Note: Because of a bug in the WPF printing classes
// this hack is unfortunately necessary in order to get the correct
// printer settings. The old/usual method often get the printer
// standard settings instead of the custom settings.
// For more information see:
// https://social.msdn.microsoft.com/Forums/vstudio/en-US/6ebf6d61-a356-41c3-a444-a24fb38416fe/printticket-not-reflecting-printing-preferences?forum=wpf
// http://stackoverflow.com/questions/20774420/getting-the-changed-printer-preferences-for-a-printer-from-controlpanel-through
var printDialog = new System.Windows.Controls.PrintDialog();
string printerName = printer.FullName;
string defaultPrinterName = printDialog.PrintQueue.FullName;
PrintTicket ticket;
if (defaultPrinterName != printerName)
{
// Temporary change default printer in order to get
// correct printer settings on the specific printer.
Win32.SetDefaultPrinter(printerName);
printDialog = new System.Windows.Controls.PrintDialog();
ticket = printDialog.PrintTicket;
Win32.SetDefaultPrinter(defaultPrinterName);
}
else
ticket = printDialog.PrintTicket;
return ticket.Clone();
}
catch
{
// If the method above fails, use the old method.
return printer.CurrentJobSettings.CurrentPrintTicket.Clone();
}
}
public static class Win32
{
[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetDefaultPrinter(string Name);
}
There is no any particular instance in the PrintDialog to show case all the printerpreferences. But you can get every info with the corresponding properties in the corresponding instance. like printDialog.PrintTicket.PagesPerSheet etc..

How to access Print Driver settings?

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

How to use Core Audio API Master Volume Control with a friendly name?

I am using this code provided here.
http://www.codeproject.com/Articles/18520/Vista-Core-Audio-API-Master-Volume-Control
I am trying to control the volume of my application and 1 additional process that my application starts. Is there a way to use this code above as per application instead of master?
Here is the code in the form
MMDeviceEnumerator DevEnum = new MMDeviceEnumerator();
device = DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia);
beiVolumControl.EditValue = (int)(device.AudioEndpointVolume.MasterVolumeLevelScalar * 100);
By comments listed there is a way to pick the device using a friendly name but I don't see any examples listed anywhere.
Here is the code used when my volume slider changes
//change the Volume
void ritbVolumeControl_EditValueChanged(object sender, EventArgs e)
{
TrackBarControl trackBar = sender as TrackBarControl;
//only use in vista or above.
if (useAlternateSound == false)
{
device.AudioEndpointVolume.MasterVolumeLevelScalar = ((float)trackBar.Value / 100.0f);
}
else
{
//probably using xp or lower.
}
// MessageBox.Show(trackBar.Value.ToString());
}
The End Goal is to Control my Application and one other process's volume if it's possible without controlling the master volume of all applications. So I can mute them and still use skype voice chat for an example. Am I going about this the wrong way?
Thanks.

POS for .Net can not detect printer

I am using POS for .Net framework version 1.12 for one of my project.
Microsoft POS for .NET is a class library that is part of Microsoft Windows Embedded for Point of Service.
http://msdn.microsoft.com/en-us/library/ms828083%28v=winembedded.10%29.aspx
private PosPrinter GetReceiptPrinter()
{
PosExplorer posExplorer = new PosExplorer(this);
DeviceInfo receiptPrinterDevice = posExplorer.GetDevice(DeviceType.PosPrinter);
return (PosPrinter)posExplorer.CreateInstance(receiptPrinterDevice);
}
above is the sample code for find the printer. Now my issue is that POS is not able to detect the printer but only open simulator with data when i run my application.
can anyone please help me ?
I had developed an application for a POS running Windows CE as the operating System but for that POS, the manufacturer provided a custom dll for invoking the operations of the printer which I consumed in my C# code. Check with the POS manufacturer and see if they are providing custom dll for the same.
Your line of code
DeviceInfo receiptPrinterDevice = posExplorer.GetDevice(DeviceType.PosPrinter);
will return the default or first PosPrinter found, which in your case looks like it is the simulator.
You need to either (1) Iterate over the collection of printers and somehow select the one you want. i.e.
foreach (DeviceInfo deviceInfo in explorer.GetDevices(DeviceType.PosPrinter))
{
if (isThisThePrinterIWant(deviceInfo)) // user defined function (maybe lookup saved preference file)
{
return (PosPrinter)posExplorer.CreateInstance(deviceInfo );
}
} // Note: GetDevices() not GetDevice()
or (2) Set a logical name for your printer (using software that came with your printer, or the POSDM utility included with Pos for .Net SDK) and change the above line to
DeviceInfo receiptPrinterDevice = posExplorer.GetDevice(DeviceType.PosPrinter, "madeUpLogicalName");
or (3) Simply set the desired printer as the default printer, and leave your code the way it is.

Categories

Resources