I have created a function for printing pdf's through adobe reader. It all works fine but I am unable to suppress the print dialog box. What I want is to print the file directly through the printer without the print dialog box popping up.
This is the function for printing but the print dialog pops up everytime it is called. I am doing a batch pdf printing so I don't want it pop every time.
public static bool PrintPDFs(string pdfFileName)
{
try
{
var proc = new Process
{
StartInfo =
{
WindowStyle = ProcessWindowStyle.Hidden,
Verb = "print",
FileName =
Registry.LocalMachine.OpenSubKey("Software")
.OpenSubKey("Microsoft")
.OpenSubKey("Windows")
.OpenSubKey("CurrentVersion")
.OpenSubKey("App Paths")
.OpenSubKey("AcroRd32.exe")
.GetValue(string.Empty)
.ToString(),
//Define location of adobe reader/command line
//switches to launch adobe in "print" mode
Arguments = string.Format(#"/p /h {0}", pdfFileName),
UseShellExecute = false,
CreateNoWindow = true
}
};
proc.Start();
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
if (!proc.HasExited)
{
proc.WaitForExit(10000);
}
proc.EnableRaisingEvents = true;
proc.Close();
KillAdobe("AcroRd32");
return true;
}
catch
{
return false;
}
}
Related
Hello my app has a button to print listed documents. The list can be quite long, like 1000 documents.
PrintDialog printDialog = new PrintDialog();
DialogResult dialogResult = printDialog.ShowDialog();
if (dialogResult == DialogResult.OK)
{
foreach (Datei datei in dateienList)
{
if (datei.dateiAuswählen == true)
{
PrinterSettings currentPrinterSettings = new PrinterSettings();
printDialog.PrinterSettings = currentPrinterSettings;
currentPrinterSettings.Copies = (short)datei.anzahlKopien;
ProcessStartInfo processInfo = new ProcessStartInfo()
{
Verb = "print",
CreateNoWindow = true,
FileName = datei.pfad,
WindowStyle = ProcessWindowStyle.Hidden
};
Process process = new Process();
process.StartInfo = processInfo;
process.Start();
process.WaitForInputIdle();
process.WaitForExit();
System.Threading.Thread.Sleep(5000);
}
}
}
At first I set Thread.Sleep timeout to 3000, but listed documents got printed out in a mixed order. So, I set it to 60000, assuming it has too little time to process the documents, but it takes way too long since every single document has to be opened, processed, and then closed even though it's set to be invisible.
Is there any solution to this problem? Or should I try another method to print out documents?
I've got a tricky issue with a console app, from which I'm trying to redirect StandardInput, StandardOutput and StandardError.
I've got a working solution for other console app - that's not a new thing for me. But this app seems to have something special, which is making impossible to redirect all outputs with a standard approach.
Console app works like this:
directly after startup writes a few lines and waits for user input
no matter what input is - console app is showing some output and again wait for new input
console app never ends, it has to be closed
I've tried already solutions based on:
StandardOutput/Error.ReadToEnd()
taki care of OutputDataReceived & ErrorDataReceived with read line by line with ReadLine
reading by char
waiting for the end of process (which is not ending, so I'm running into a deadlock)
to start console app in a preloaded cmd.exe and grab this (StandardOutput stopped to show just after launch of this console app)
to manually flush input
All the time I had completely no output and no error stream from console app - nothing.
After a multitude attempts I've discovered, that I can receive StandardOutput only when I'll close StandardInput after programatically inputting the data.
But in this case, console app is going wild, falling into loop of writing few lines to StandardOutput as on start-up, which makes final output big and full of garbages.
With MedallionShell library I'm able to try to gracefully kill it with Ctrl+C, but this solution is still far from acceptable, because:
sometimes console app will produce so much garbages before I will be able to kill it, that it crashes my app
even if this won't crash, searching for expected output in a lot of garbages is nasty and tragically slows down automatization (6000 records in... 15 minutes)
I'm unable to provide more than one input at a time, so I have to start console app just to receive one output, close and start again for another output
I've got no sources for that console app, so I'm even not able to recreate the issue or fix it - it's some very legacy app at my company, which I'm trying to make at least a bit automatic...
Code, with which I've got at least anything now (with MediallionShell):
var command = Command.Run(Environment.CurrentDirectory + #"\console_app.exe");
command.StandardInput.WriteLine("expected_input");
command.StandardInput.Close(); // without that I'll never receive any output or error stream from this stubborn console app
command.TrySignalAsync(CommandSignal.ControlC); // attempt to kill gracefully, not always successfull...
var result = command.Result;
textBox1.AppendText(String.Join(Environment.NewLine, command.GetOutputAndErrorLines().ToArray().Take(10))); // trying to get rid of garbages
command.Kill(); // additional kill attempt if Ctrl+C didn't help, sometimes even this fails
Any help will be appreciated, I'm also still searching for solution and now I'm checking this one: PostMessage not working with console window whose output is redirected and read asynchronously but author there had an output and I don't...
You haven't provided a sample Console program to test with, but something like the following may work:
Create a Console project (Console (.NET Framework)) - used for testing
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleTestApp
{
class Program
{
static void Main(string[] args)
{
//prompt for input - 1st prompt
Console.Write("Please enter filename: ");
string filename = Console.ReadLine();
if (System.IO.File.Exists(filename))
{
Console.WriteLine("'" + filename + "' exists.");
}
else
{
Console.Error.WriteLine("'" + filename + "' doesn't exist.");
}
//prompt for input - 2nd prompt
Console.Write("Would you like to exit? ");
string answer = Console.ReadLine();
Console.WriteLine("Your answer was: " + answer);
Console.WriteLine("Operation complete.");
}
}
}
Then, create a Windows Forms project Windows Forms (.NET Framework) and run one of the following:
Option 1:
private void RunCmd(string exePath, string arguments = null)
{
//create new instance
ProcessStartInfo startInfo = new ProcessStartInfo(exePath, arguments);
startInfo.Arguments = arguments; //arguments
startInfo.CreateNoWindow = true; //don't create a window
startInfo.RedirectStandardError = true; //redirect standard error
startInfo.RedirectStandardOutput = true; //redirect standard output
startInfo.RedirectStandardInput = true;
startInfo.UseShellExecute = false; //if true, uses 'ShellExecute'; if false, uses 'CreateProcess'
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.ErrorDialog = false;
//create new instance
using (Process p = new Process { StartInfo = startInfo, EnableRaisingEvents = true })
{
//subscribe to event and add event handler code
p.ErrorDataReceived += (sender, e) =>
{
if (!String.IsNullOrEmpty(e.Data))
{
//ToDo: add desired code
Debug.WriteLine("Error: " + e.Data);
}
};
//subscribe to event and add event handler code
p.OutputDataReceived += (sender, e) =>
{
if (!String.IsNullOrEmpty(e.Data))
{
//ToDo: add desired code
Debug.WriteLine("Output: " + e.Data);
}
};
p.Start(); //start
p.BeginErrorReadLine(); //begin async reading for standard error
p.BeginOutputReadLine(); //begin async reading for standard output
using (StreamWriter sw = p.StandardInput)
{
//provide values for each input prompt
//ToDo: add values for each input prompt - changing the for loop as necessary
for (int i = 0; i < 2; i++)
{
if (i == 0)
sw.WriteLine(#"C:\Temp\Test1.txt"); //1st prompt
else if (i == 1)
sw.WriteLine("Yes"); //2nd prompt
else
break; //exit
}
}
//waits until the process is finished before continuing
p.WaitForExit();
}
}
Option 2:
private void RunCmd(string exePath, string arguments = null)
{
//create new instance
ProcessStartInfo startInfo = new ProcessStartInfo(exePath, arguments);
startInfo.Arguments = arguments; //arguments
startInfo.CreateNoWindow = true; //don't create a window
startInfo.RedirectStandardError = true; //redirect standard error
startInfo.RedirectStandardOutput = true; //redirect standard output
startInfo.RedirectStandardInput = true;
startInfo.UseShellExecute = false; //if true, uses 'ShellExecute'; if false, uses 'CreateProcess'
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.ErrorDialog = false;
//create new instance
using (Process p = new Process { StartInfo = startInfo, EnableRaisingEvents = true })
{
//subscribe to event and add event handler code
p.ErrorDataReceived += (sender, e) =>
{
if (!String.IsNullOrEmpty(e.Data))
{
//ToDo: add desired code
Debug.WriteLine("Error: " + e.Data);
}
};
//subscribe to event and add event handler code
p.OutputDataReceived += (sender, e) =>
{
if (!String.IsNullOrEmpty(e.Data))
{
//ToDo: add desired code
Debug.WriteLine("Output: " + e.Data);
}
};
p.Start(); //start
p.BeginErrorReadLine(); //begin async reading for standard error
p.BeginOutputReadLine(); //begin async reading for standard output
using (StreamWriter sw = p.StandardInput)
{
//provide values for each input prompt
//ToDo: add values for each input prompt - changing the for loop as necessary
sw.WriteLine(#"C:\Temp\Test1.txt"); //1st prompt
sw.WriteLine("Yes"); //2nd prompt
}
//waits until the process is finished before continuing
p.WaitForExit();
}
}
Option 3:
Note: This one is modified from here.
private void RunCmd(string exePath, string arguments = null)
{
//create new instance
ProcessStartInfo startInfo = new ProcessStartInfo(exePath, arguments);
startInfo.Arguments = arguments; //arguments
startInfo.CreateNoWindow = true; //don't create a window
startInfo.RedirectStandardError = true; //redirect standard error
startInfo.RedirectStandardOutput = true; //redirect standard output
startInfo.RedirectStandardInput = true;
startInfo.UseShellExecute = false; //if true, uses 'ShellExecute'; if false, uses 'CreateProcess'
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.ErrorDialog = false;
//create new instance
using (Process p = new Process { StartInfo = startInfo, EnableRaisingEvents = true })
{
p.Start(); //start
Read(p.StandardOutput);
Read(p.StandardError);
using (StreamWriter sw = p.StandardInput)
{
//provide values for each input prompt
//ToDo: add values for each input prompt - changing the for loop as necessary
sw.WriteLine(#"C:\Temp\Test1.txt"); //1st prompt
sw.WriteLine("Yes"); //2nd prompt
}
//waits until the process is finished before continuing
p.WaitForExit();
}
}
private static void Read(StreamReader reader)
{
new System.Threading.Thread(() =>
{
while (true)
{
int current;
while ((current = reader.Read()) >= 0)
Console.Write((char)current);
}
}).Start();
}
I am trying print pdf file from application to network printer it will take more than 7 minutes but the pdf file sent immediately to the printer queue and i also try to one manual print in the same server open the adobe and give one test print the document is printed with 2 minutes.not able to find why the latency is there?
private static async Task PrintPDFfilemethod(string strPath)
{
try
{
ProcessStartInfo processStartInfo = new ProcessStartInfo()
{
Verb = "printto",
FileName = printfilenamewithpath,
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden
};
processStartInfo.Arguments = "\"" + printername + "\"";
Process process = new Process()
{
StartInfo = processStartInfo
};
process.Start();
Thread.Sleep(30000);
process.WaitForInputIdle();
Thread.Sleep(30000);
if (!process.CloseMainWindow())
process.Kill();
}
catch(Exception ex)
{
}
}
I want to print existing .pdf files in one click.
It works fine when i only print one file at a time, but when choose to print multiple files at once it only prints one file.
Here's my code:
List<string> ListFilePath; //Assume i have a collection of filepath stored here
foreach(string FilePath in ListFilePath)
{
Process proc = new Process();
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.StartInfo.Verb = "print";
proc.StartInfo.FileName = FilePath;
proc.StartInfo.Arguments = String.Format(#"/p /h {0}", FilePath);
proc.StartInfo.CreateNoWindow = true;
proc.Start();
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
if (proc.HasExited == false)
{
proc.WaitForExit(10000);
}
proc.EnableRaisingEvents = true;
proc.Close();
}
Where's my mistake?
Your code is launching a process and creating a printing job on the server. Are you sure that's right, and it's not supposed to print on the client instead?
One thing you might try is to merge all pdfs into one (PDFSharp does that nicely) and then print just the merged pdf.
Can You assign to the event handler, and stop the process then ?
Not inside this method.
This works great for me
foreach (string pdf in ListFilePath)
{
string filename = System.IO.Path.GetFileName(pdf);
string fullPath = (#"U:\Define\Full\Path" + filename);
Print(fullPath, 'PrinterNameHere');
}
public static bool Print(string file, string printer)
{
try
{
Process.Start(Registry.LocalMachine.OpenSubKey(
#"SOFTWARE\Microsoft\Windows\CurrentVersion" +
#"\App Paths\AcroRd32.exe").GetValue("").ToString(),
string.Format("/h /t \"{0}\" \"{1}\"", file, printer));
return true;
}
catch
{ return false; }
}
I have a GUI that wraps a console application to improve user experience. I'm using the Process class to spin off the console executable. I want the console window to come up, and I will manually write abbreviated output to it. Then, once the executable is finished, the console window will close and control passes back to the GUI.
However, it is an interactive program, requiring me to redirect both StandardIn and StandardOut. The problem is that the very act of redirecting the input stops all output from coming to the console.
I've included all the output code as I had it, but commented out. As it is, a console window will open and the prompts will appear, waiting for user input. If I uncomment RedirectStandardIn, the window appears, but simply remains blank. Am I misunderstanding the role of Process.StandardInput?
class HandleExecutable
{
...
public void callExecutable(string executable, string args, string inputStr)
{
string commandLine = executable;
ProcessStartInfo psi = new ProcessStartInfo(commandLine);
psi.UseShellExecute = false;
psi.LoadUserProfile = false;
//psi.RedirectStandardOutput = true;
//psi.RedirectStandardError = true;
/* UNCOMMENT BELOW WILL CAUSE NO OUTPUT TO BE PUT TO THE CONSOLE */
//psi.RedirectStandardInput = true;
psi.WindowStyle = ProcessWindowStyle.Minimized;
psi.Arguments = args;
Process p = new Process();
p.StartInfo = psi;
try
{
p.Start();
//p.StandardInput.WriteLine(inputStr);
//p.BeginOutputReadLine();
//p.BeginErrorReadLine();
if (outputHandler != null) p.OutputDataReceived += outputHandler;
if (errorHandler != null) p.ErrorDataReceived += errorHandler;
p.WaitForExit();
p.Close();
p.Dispose();
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message);
}
}
}