How to Print any document in a SELECTED printer - c#

I would like to print any document such as pdf,word,excel or text files in a selected printer using .net .I have got success to do such printing in the default printer .The only issue now is to print in the selected printer.
Here is the code for the printing.
public bool Print(string FilePath)
{
if (File.Exists(FilePath)) {
if (ShellExecute((System.IntPtr )1, "Print", FilePath, "", Directory.GetDirectoryRoot(FilePath), SW_SHOWNORMAL).ToInt32() <= 32) {
return false;
} else {
return true;
}
} else {
return false;
}
}

Process printJob = new Process();
printJob.StartInfo.FileName = path;
printJob.StartInfo.UseShellExecute = true;
printJob.StartInfo.Verb = "printto";
printJob.StartInfo.CreateNoWindow = true;
printJob.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
printJob.StartInfo.Arguments = "\"" + printerAddress + "\"" + " " + printerExtraParameters;
printJob.StartInfo.WorkingDirectory = Path.GetDirectoryName(path);
printJob.Start();

What file format are you testing with success to the default printer?
Its not possible to just send "any" document to a printer, generally the specific file format needs to be interpretted by an application that can read the file format then render it to a printer or a file that can be interpretted by the printer.
In most cases if you can render to a PostScript or PDF you can get its to print using a single interpretter.

Related

How to use printer on server [duplicate]

This question already has an answer here:
How to run console application which is send pdf to printer in server?
(1 answer)
Closed 2 years ago.
I download .zip file from outlook then send pdf files to printer. It works on my local machine while compiling, However I setup published app on server, it downloads .zip file from outlook and open it but it can not send to printer . How can I handle that?
This is my code:
static void Main(string[] args)
{
ExchangeService exchange = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
exchange.Credentials = new WebCredentials("mail#", "password");
exchange.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
if (exchange != null)
{
SearchFilter sf = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
FindItemsResults<Item> result = exchange.FindItems(WellKnownFolderName.Inbox, sf, new ItemView(1));
foreach (Item item in result)
{
EmailMessage message = EmailMessage.Bind(exchange, item.Id);
message.IsRead = true;
message.Update(ConflictResolutionMode.AutoResolve);
List<Attachment> zipList = message.Attachments.AsEnumerable().Where(x => x.Name.Contains(".zip")).ToList();
foreach (Attachment Attachment in zipList)
{
if (Attachment is FileAttachment)
{
FileAttachment f = Attachment as FileAttachment;
f.Load("C:\\TEST\\" + f.Name);
string zipPath = #"C:\TEST\" + f.Name;
string extractPath = #"C:\TEST\" + Path.GetRandomFileName();
ZipFile.ExtractToDirectory(zipPath, extractPath);
string[] filePaths = Directory.GetFiles(extractPath, "*.pdf",
SearchOption.TopDirectoryOnly);
foreach (string path in filePaths)
{
SendToPrinter(path);
}
}
}
}
}
}
static void SendToPrinter(string path)
{
try
{
var printerName = "EPSON L310 Series";
ProcessStartInfo info = new ProcessStartInfo(path);
info.Verb = "PrintTo";
info.UseShellExecute = false;
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
info.Arguments = "\"" + printerName + "\"";
Process p = new Process();
p.StartInfo = info;
p.Start();
p.WaitForInputIdle();
System.Threading.Thread.Sleep(3000);
if (false == p.CloseMainWindow())
p.Kill();
}
catch (Exception ex)
{
Console.WriteLine("error:", ex.Message);
Console.ReadLine();
}
}
As I said, everything is work fine but printer not working. I can print pdf manually I mean machine works. Also this app works on my local machine
You need to change:
info.UseShellExecute = false;
to:
info.UseShellExecute = true;
since the path is a path to a PDF file, not an executable.
As per the docs:
When you use the operating system shell to start processes, you can
start any document (which is any registered file type associated with
an executable that has a default open action) and perform operations
on the file, such as printing, by using the Process object. When
UseShellExecute is false, you can start only executables by using the
Process object.
Additionally:
If you set the WindowStyle to ProcessWindowStyle.Hidden,
UseShellExecute must be set to true.
You are using Hidden - thus UseShellExecute must be true.

Print a document passing arguments to Process

I'm working on sending documents to a specific printer, in this case the "Microsoft to PDF" one.
Everything work fine except that a prompt comes up asking for the folder where to save the pdf and its name.
Process printJob = new Process();
printJob.StartInfo.FileName = pathToFile;
printJob.StartInfo.UseShellExecute = true;
printJob.StartInfo.Verb = "printto";
printJob.StartInfo.CreateNoWindow = true;
printJob.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
printJob.StartInfo.Arguments = "\"" + pdfPrinter + "\"";
printJob.StartInfo.WorkingDirectory = Path.GetDirectoryName(destinationPath);
printJob.Start();
Is there a way to pass any paramenter to printJob.StartInfo.Arguments such destination path and filename and avoid the prompt?

Create pdf from html using wkhtmltopdf

i am genrating pdf from html code.Here i find code for generating using wkhtmltopdf
private void WritePDF(string HTML)
{
string inFileName,
outFileName,
tempPath;
Process p;
System.IO.StreamWriter stdin;
ProcessStartInfo psi = new ProcessStartInfo();
tempPath = Request.PhysicalApplicationPath + "ExcelFiles\\";
inFileName = Session.SessionID + ".htm";
outFileName = Session.SessionID + ".pdf";
// run the conversion utility
psi.UseShellExecute = false;
psi.FileName = "E:\\wkhtmltopdf";
psi.CreateNoWindow = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
// note that we tell wkhtmltopdf to be quiet and not run scripts
// NOTE: I couldn't figure out a way to get both stdin and stdout redirected so we have to write to a file and then clean up afterwards
psi.Arguments = "-q -n - " + tempPath + outFileName;
p = Process.Start(psi);
try
{
stdin = p.StandardInput;
stdin.AutoFlush = true;
stdin.Write(HTML);
stdin.Close();
if (p.WaitForExit(15000))
{
// NOTE: the application hangs when we use WriteFile (due to the Delete below?); this works
Response.BinaryWrite(System.IO.File.ReadAllBytes(tempPath + outFileName));
//Response.WriteFile(tempPath + outFileName);
}
}
finally
{
p.Close();
p.Dispose();
}
// delete the pdf
System.IO.File.Delete(tempPath + outFileName);
}
I found this answer from here
how to pass html as a string using wkhtmltopdf?
Here i get error Could not find file on
if (p.WaitForExit(15000))
{
// NOTE: the application hangs when we use WriteFile (due to the Delete below?); this works
Response.BinaryWrite(System.IO.File.ReadAllBytes(tempPath + outFileName));
//Response.WriteFile(tempPath + outFileName);
}
how i can create file for this now?
It gets Created on stdin.Close();
Please check if the html in stdin.Write(HTML); has some content in it

How to print a PDF file from code? [duplicate]

This question already has answers here:
How can I send a file document to the printer and have it print?
(12 answers)
Windows 8 blows error on c# process for printing pdf file, how?
(1 answer)
Closed 9 years ago.
I've been developing an application in visual c# which needs to print an existing pdf file at the press of a button.
I've been using the System.Diagnostics.Process method to print but it fails to work as desired in a Windows 8 environment as the "Printto" command doesn't seem to work there.
I would like to use an alternative such as possibly the System.Drawing.Printing.PrintDocument which had an example that works with text files but when I tried with a pdf it was printing random characters instead.
My google searches for such seem to come up empty or I'm not entering the right keywords, but I need a solution which not only prints pdf to target printer but can determine if the printer is ready, offline or out of paper as well as an error catch.
Please advise as I'm also willing to look at any SDK or third party routes recommendable.
edit: added code snippet I'm currently using:
string defFile = (Path.Combine(GlobalVars.pdfPath, tkt_no + "_DEF.pdf"));
string rwPrinter = "";
if (GlobalVars.useDefaultPrinter == false)
{
foreach (string strPrinter in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
{
if (strPrinter.StartsWith("ZDesigner"))
{
rwPrinter = strPrinter;
break;
}
}
}
if (jobdo.Equals("print"))
{
Process process = new Process();
//process.StartInfo.CreateNoWindow = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.FileName = defFile;
if (rwPrinter.Length > 0)
{
process.StartInfo.Verb = "printto";
//process.StartInfo.Verb = (Path.Combine(System.Windows.Forms.Application.StartupPath, "printto.exe"));
process.StartInfo.Arguments = "\"" + rwPrinter + "\"";
}
else
{
process.StartInfo.Verb = "print";
}
try
{
process.Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
process.WaitForInputIdle();
//while (process.MainWindowHandle == IntPtr.Zero)
//{
// Thread.Sleep(20);
// process.Refresh();
//}
Thread.Sleep(7000);
try
{
process.Kill();
}
catch { }
// close any occurrences of Adobe Reader that may not close through a citrix environment regardless
foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcesses())
{
if (p.ProcessName.Equals("AcroRd32"))
{
ObjectQuery sq = new ObjectQuery
("Select * from Win32_Process where ProcessID = '" + p.Id + "'");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(sq);
foreach (ManagementObject oReturn in searcher.Get())
{
string[] o = new string[2];
oReturn.InvokeMethod("GetOwner", (object[])o);
if(o[0] != null)
if(o[0].Equals(System.Environment.UserName))
p.Kill();
}
}
}
if (rwPrinter == "")
{
rwPrinter = "the default printer";
}
else
MessageBox.Show("Ticket " + tkt_no + " was printed to " + rwPrinter + ".");
}
Please see this, using iTextSharp library you can easily create PDF file:
http://sourceforge.net/projects/itextsharp/

Open and print PDF files

I'd like to open and print all PDF files located in a given folder. The files are named according to the following pattern:
NameOfThePrinter_Timestamp.pdf
Now I want to print those files using the corresponding printer:
static void Main(string[] args)
{
string pdf = #"C:\PathToFolder";
if (Directory.GetFiles(pdf).Length > 0)
{
string[] files = Directory.GetFiles(pdf);
var adobe = Registry.LocalMachine.OpenSubKey("Software").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("App Paths").OpenSubKey("AcroRd32.exe");
var path = adobe.GetValue("");
string acrobat = path.ToString();
for (int i = 0; i < files.Length; i++)
{
Process process = new Process();
process.StartInfo.FileName = acrobat;
process.StartInfo.Verb = "printto";
process.StartInfo.Arguments = "/p /s /h \"" + files[i] + "\"";
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.Start();
DateTime start = DateTime.Now;
IntPtr handle = IntPtr.Zero;
while (handle == IntPtr.Zero && DateTime.Now - start <= TimeSpan.FromSeconds(2))
{
try
{
System.Threading.Thread.Sleep(50);
handle = process.MainWindowHandle;
} catch (Exception) { }
}
foreach (String verb in process.StartInfo.Verbs)
{
// Display the possible verbs.
Console.WriteLine(" {0}. {1}", i.ToString(), verb);
i++;
}
System.Threading.Thread.Sleep(10000);
Console.Out.WriteLine("File: " + files[i] + " is printing!");
process.Kill();
}
foreach (string str in files)
{
File.Delete(str);
}
Console.Out.WriteLine("Files are deleted!");
}
}
My question is: How can I pass the printer name as parameter?
Here I've tried something, but it either throws and error or prints to the default printer:
process.StartInfo.Arguments = "/p /s /h \"" + files[i] + "\"";
You can use Ghostscript to send the PDF document to the printer.
Here you can find a sample how to send the PDF document to printer: How to print PDF on default network printer using GhostScript (gswin32c.exe) shell command
And here you can find Ghostscript wrapper for .NET if you want to control Ghostscript directly without calling .exe file: http://ghostscriptnet.codeplex.com
function printDisclosureDocument() {
var doc = document.getElementById('pdfDocument');
if (doc == 'undefined' || doc == null) {
var pdfbox = document.createElement('embed');
pdfbox.type = 'application/pdf';
pdfbox.src = 'ShowPDF.aspx?refid=' + $('#MainContent_hdnRefId').val();
pdfbox.width = '1';
pdfbox.height = '1';
pdfbox.id = 'pdfDocument';
document.body.appendChild(pdfbox);
}
if (doc != null && doc != 'undefined') {
//Wait until PDF is ready to print
if (typeof doc.print === 'undefined') {
setTimeout(function () { printDisclosureDocument(); }, 500);
} else {
doc.print();
}
}
else {
setTimeout(function () { printDisclosureDocument(); }, 500);
}
}

Categories