Print multiple copies of pdf - c#

I am currently using the below code for printing a pdf using Foxit Reader software. Now my problem is I want to print multiple copies of a file. Could anyone let me know how to specify the number of copies while printing a pdf in the below code.
[Edit]
I dont want to use a loop to print multiple copies of pdf. I want to specify it only as a command line argument.
Any help much appreciated :)
Process process = new System.Diagnostics.Process();
process.EnableRaisingEvents = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.FileName = foxitReaderInstalledPath;
string arguments = String.Format(#"-t ""{0}"" ""{1}""", this.Path, printerName);
process.StartInfo.Arguments = arguments;
process.Start();
process.WaitForExit();

According to the Foxit manual there is no option to do what you want except with a loop (which you don't want to use).
Either you use some PDF library for .NET -there are plenty free and commercial ones out there (see for example .NET library to print PDF files )- or you use for example Acrobat reader for printing (IIRC it has a commandline switch to achieve what you want)...

Just put that in a loop. You can always manipulate the termination of the process later.
It'd be nice to put it in the Arguments, but I don't think FoxIt supports it that I know of.
int numberOfCopies = 2;
Process process = new System.Diagnostics.Process();
for (int i = 1; i <= numberOfCopies; i++)
{
process.EnableRaisingEvents = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.FileName = foxitReaderInstalledPath;
string arguments = String.Format(#"-t ""{0}"" ""{1}""", this.Path, printerName);
process.StartInfo.Arguments = arguments;
process.Start();
}

Related

Unity C# Encoding Type

I create simple unity application, there is button that give user print a picture. When button is clicked, it will run a command in cmd but I get this message,
'cd' is not recognized as an internal or external command,
operable program or batch file.
I search the web, it says I need to change encoding type but I have do it in Notepad++ (I change it from UTF-8 BOM to ANSI) but it still no work.
Here is my code, in case I am wrong.
string fullCommand = "rundll32 C:/WINDOWS/system32/shimgvw.dll,ImageView_PrintTo " + filePath + printerName
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.CreateNoWindow = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.Arguments = "/c " + fullCommand;
process.Start();
This is my reference
How to direct printing of photo or text using Unity without preview
I expect it to print the expected file but it do not. I hope someone can guide me. Thank you for helping.
Cheers
Kev

How to programmatically print coloured pdfs?

I want to print some pdfs programmatically.
This code works and will print any pdf:
ProcessStartInfo psInfo = new ProcessStartInfo();
psInfo.Verb = "Print"; // or "PrintTo"
psInfo.FileName = pdfFileName;
psInfo.Arguments = String.Format("/p /h \"{0}\" \"{1}\"", pdfFileName, printerName);
psInfo.WindowStyle = ProcessWindowStyle.Hidden;
psInfo.CreateNoWindow = true;
psInfo.UseShellExecute = true;
Process process = Process.Start(psInfo);
process.Close();
The problem:
I actually want to print coloured. Things like
PageSettings.Color
won't work.
One solution could be, to set the settings of the network printer from grey to coloured, but actually I dont have the accessrights to change them with powershell or something like that.
So, I have some existing pdfs I want to print to print coloured.
There are some NuGet-packages, but i'm not allowed to use them.
The printer is able to print with colour!

C# Redirecting process results to a text file

I've been racking my brain trying to figure out why I can not use >> (append) as a part of my p.StartInfo.Argument. When I remove ">" it works perfectly, but the moment I try to use ">" or ">>" I get a "Incorrect Parameter" error. I've gone ahead and wrote my program without > or >> and just stored the output into a string and write it to a file later. Could someone explain why ">" or ">>" would not work in this situation?
// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "attrib.exe";
startInfo.Arguments = "/S *.jpg > mypics.txt";
p.Start();
The output redirection operator > is a feature of cmd.exe, not the operating system. The naive way to use it is hence to call cmd as so:
p.StartInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C \"attrib.exe /S *.jpg > mypics.txt\"";
The proper way to redirect the output, however, is to first set StartInfo.RedirectStandardOutput to true (which you did), and then pipe the output from Process.StandardOutput to the file, as so:
using(StreamWriter file = new StreamWriter("mypics.txt")) {
p.StandardOutput.CopyTo(file);
}
Or, async version:
using(StreamWriter file = new StreamWriter("mypics.txt")) {
await p.StandardOutput.CopyToAsync(file);
}
That's because > and >> are not arguments interpreted by attrib.exe, they're instructions to cmd.exe.
You could try instead something like:
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c attrib.exe /S *.jpg > mypics.txt";
Also, this is a red herring:
p.StartInfo.RedirectStandardOutput = true;
If you wanted to read the output in C# code and write the file yourself, you'd use this option. It's not helpful for using the > output redirector.
SlugFiller's solution is good but doesn't work reliably with large amounts of output. The problem is that if the process outputs too much text it hangs because the stream reaches the maximum buffer size. In other words the stream needs to be spooled out as the process runs, preventing the buffer from ever filling up.
However, there is a way to do this using a task to receive data from the output stream and spool it out in real-time.
// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "attrib.exe";
startInfo.Arguments = "/S *.jpg > mypics.txt";
p.Start();
Thread stdoutThread = new Thread(new ThreadStart(WriteStandardOutput));
stdoutThread.IsBackground = true;
stdoutThread.Name = "stdout_writer";
stdoutThread.Start();
private void WriteStandardOutput()
{
using (StreamWriter sw = File.CreateText(ConsoleLogFileFullPath))
using (StreamReader sr = p.StandardOutput)
{
for (;;)
{
string line = sr.ReadLine();
if (line == null)
break;
sw.WriteLine(textLine);
}
sw.Flush();
}
}
At some point be sure to call stdoutThread.Join() to make sure that the thread completes. I have tested this with some code that generates large amounts of output and it's still possible to overflow the buffer, or to break ReadLine() with extremely long lines, but it does work for very fast output in the order of a few thousand 80 character lines per second.

Run "tf.exe status" in C# and save the result

I´m trying to create a small console app in c#. I want to run the program and save all pending changes in TFS to a .txt file. But I cant get the arguments to work. Can someone help me?
Here is my code i haved done so far:
string argument = "#tf.exe status /collection:http://tiffany:8080/tfs/ /user:* /format:detailed >c:\\Status\\Detailed.txt";
try
{
Process process = new Process();
process.StartInfo.Arguments = "#call" + " " + "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\Common7\\Tools\\VsDevCmd.bat";
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Verb = "runas";
process.StartInfo.Arguments = argument;
process.StartInfo.CreateNoWindow = false;
process.Start();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.ReadKey();
}
aI'm not really sure that I understand what you're trying to call, exactly.
Let's assume you want to run the following command line from a C# application, as if you would call it from a command line:
tf.exe status /collection:http://tiffany:8080/tfs/ /user:* /format:detailed >c:\\Status\\Detailed.txt"
I would use this code:
string arguments = #"/C tf.exe status /collection:http://tiffany:8080/tfs/ /user:* /format:detailed >c:\\Status\\Detailed.txt";
this.process = new Process();
this.process.StartInfo.FileName = #"cmd.exe";
this.process.StartInfo.Arguments = arguments;
this.process.Start();
Edit:
If that's all your console app does, why not consider creating a batch (.BAT / .CMD) file instead of a C# application?
Instead of running a command line tool you could leverage the TFS API.
There are many articles out there, e.g. Code project article on topic
and
Sample code directly from the MSDN
I suppose you have to read standard error and output from process started:
Process process = new Process();
process.StartInfo.Arguments = #"status PATH /recursive";
process.StartInfo.FileName = "tf.exe";
process.StartInfo.CreateNoWindow = false;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
var st = process.StandardOutput.ReadToEnd();
var err = process.StandardError.ReadToEnd();
But parsing tf output is not easy and I'd like to suggest to use TFS API as #Mare said
You do not need to create an application in C # to save in a text file. Just use the parameters (...) > [file name].txt at the end of the command.
The ">" symbol send the result of any command to a file.

Printing a PDF Silently with Adobe Acrobat

I'm having 2 issues when trying to print a pdf silently in C# using adobe acrobat. I'm printing the pdfs using Process.Start().
The first issue is that I cannot launch Adobe Acrobat without specifying the full path to the executable. I assume it doesn't add it to your path when you install it. Is there an easy way to launch the newest version of acrobat on a machine without specifying full path names? I'm worried that the client is going to do an update and break my code that launches this. I'm also concerned with them installing this on machines with different versions of windows (install paths are different in 64 bit environment vs. 32 bit).
My second problem is the fact that whenever I launch acrobat and print it still leaves the acrobat window open. I thought that the command line parameters I was using would suppress all of this but apparently not.
I'm trying to launch adobe acrobat from the command line with the following syntax:
C:\Program Files (x86)\Adobe\Reader 10.0\Reader>AcroRd32.exe /t "Label.pdf" "HP4000" "HP LaserJet 4100 Series PCL6" "out.pdf"
It prints out fine but it still leaves the acrobat window up. Is there any other solution besides going out and killing the process programmatically?
I ended up bailing on Adobe Acrobat here and going with FoxIt Reader (Free pdf reader) to do my pdf printing. This is the code I'm using to print via FoxIt in C#:
Process pdfProcess = new Process();
pdfProcess.StartInfo.FileName = #"C:\Program Files (x86)\Foxit Software\Foxit Reader\Foxit Reader.exe";
pdfProcess.StartInfo.Arguments = string.Format(#"-p {0}", fileNameToSave);
pdfProcess.Start();
The above code prints to the default printer but there are command line parameters you can use to specify file and printer. You can use the following syntax:
Foxit Reader.exe -t "pdf filename" "printer name"
Update:
Apparently earlier versions of acrobat do not have the problem outlined above either. If you use a much older version (4.x or something similar) it does not exhibit this problem.
Some printers do support native pdf printing as well so it's possible to send the raw pdf data to the printer and it might print it. See https://support.microsoft.com/en-us/kb/322091 for sending raw data to the printer.
Update 2
In later versions of our software we ended up using a paid product:
http://www.pdfprinting.net/
Nick's answer looked good to me, so I translated it to c#. It works!
using System.Diagnostics;
namespace Whatever
{
static class pdfPrint
{
public static void pdfTest(string pdfFileName)
{
string processFilename = Microsoft.Win32.Registry.LocalMachine
.OpenSubKey("Software")
.OpenSubKey("Microsoft")
.OpenSubKey("Windows")
.OpenSubKey("CurrentVersion")
.OpenSubKey("App Paths")
.OpenSubKey("AcroRd32.exe")
.GetValue(String.Empty).ToString();
ProcessStartInfo info = new ProcessStartInfo();
info.Verb = "print";
info.FileName = processFilename;
info.Arguments = String.Format("/p /h {0}", pdfFileName);
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
//(It won't be hidden anyway... thanks Adobe!)
info.UseShellExecute = false;
Process p = Process.Start(info);
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
int counter = 0;
while (!p.HasExited)
{
System.Threading.Thread.Sleep(1000);
counter += 1;
if (counter == 5) break;
}
if (!p.HasExited)
{
p.CloseMainWindow();
p.Kill();
}
}
}
}
I've tried both Adobe Reader and Foxit without luck. The current versions of both are very fond of popping up windows and leaving processes running. Ended up using Sumatra PDF which is very unobtrusive. Here's the code I use. Not a trace of any windows and process exits nicely when it's done printing.
public static void SumatraPrint(string pdfFile, string printer)
{
var exePath = Registry.LocalMachine.OpenSubKey(
#"SOFTWARE\Microsoft\Windows\CurrentVersion" +
#"\App Paths\SumatraPDF.exe").GetValue("").ToString();
var args = $"-print-to \"{printer}\" {pdfFile}";
var process = Process.Start(exePath, args);
process.WaitForExit();
}
The following is tested in both Acrobat Reader 8.1.3 and Acrobat Pro 11.0.06, and the following functionality is confirmed:
Locates the default Acrobat executable on the system
Sends the file to the local printer
Closes Acrobat, regardless of version
string applicationPath;
var printApplicationRegistryPaths = new[]
{
#"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Acrobat.exe",
#"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\AcroRD32.exe"
};
foreach (var printApplicationRegistryPath in printApplicationRegistryPaths)
{
using (var regKeyAppRoot = Registry.LocalMachine.OpenSubKey(printApplicationRegistryPath))
{
if (regKeyAppRoot == null)
{
continue;
}
applicationPath = (string)regKeyAppRoot.GetValue(null);
if (!string.IsNullOrEmpty(applicationPath))
{
return applicationPath;
}
}
}
// Print to Acrobat
const string flagNoSplashScreen = "/s";
const string flagOpenMinimized = "/h";
var flagPrintFileToPrinter = string.Format("/t \"{0}\" \"{1}\"", printFileName, printerName);
var args = string.Format("{0} {1} {2}", flagNoSplashScreen, flagOpenMinimized, flagPrintFileToPrinter);
var startInfo = new ProcessStartInfo
{
FileName = printApplicationPath,
Arguments = args,
CreateNoWindow = true,
ErrorDialog = false,
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden
};
var process = Process.Start(startInfo);
// Close Acrobat regardless of version
if (process != null)
{
process.WaitForInputIdle();
process.CloseMainWindow();
}
got another solution .. its combination of other snippets from stackOverflow. When I call CloseMainWindow, and then call Kill .. adobe closes down
Dim info As New ProcessStartInfo()
info.Verb = "print"
info.FileName = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("App Paths").OpenSubKey("AcroRd32.exe").GetValue(String.Empty).ToString()
info.Arguments = String.Format("/p /h {0}", "c:\log\test.pdf")
info.CreateNoWindow = True
info.WindowStyle = ProcessWindowStyle.Hidden
info.UseShellExecute = False
Dim p As Process = Process.Start(info)
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
Dim counter As Integer = 0
Do Until p.HasExited
System.Threading.Thread.Sleep(1000)
counter += 1
If counter = 5 Then
Exit Do
End If
Loop
If p.HasExited = False Then
p.CloseMainWindow()
p.Kill()
End If
Problem 1
You may be able to work your way around the registry. In HKEY_CLASSES_ROOT\.pdf\PersistentHandler\(Default) you should find a CLSID that points to a value found in one of two places. Either the CLSID folder of the same key, or (for 64 bit systems) one step down in Wow6432Node\CLSID then in that CLSID's key.
Within that key you can look for LocalServer32 and find the default string value pointing to the current exe path.
I'm not 100% on any of this, but seems plausible (though you're going to have to verify on multiple environments to confirm that in-fact locates the process you're looking for).
(Here are the docs on registry keys involved regarding PersistentHandlers)
Problem 2
Probably using the CreateNoWindow of the Process StartInfo.
Process p = new Process();
p.StartInfo.FileName = #"C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe";
p.StartInfo.Arguments = "/t \"Label.pdf\" \"HP4000\" \"HP LaserJet 4100 Series PCL6\" \"out.pdf\"";
p.CreateNoWindow = true;
p.Start();
p.WaitForExit();
(only a guess however, but I'm sure a little testing will prove it to work/not work)
If you use Acrobat reader 4.0 you can do things like this:
"C:\Program Files\Adobe\Acrobat 4.0\Reader\Acrord32.exe" /t /s "U:\PDF_MS\SM003067K08.pdf" Planning_H2
BUT if the PDF file has been created in a newer version of Acrobat an invisible window opens
For Problem 2
Using /h param will open the Acrobat or Adobe Reader in minimized window.
Example:
C:\Program Files (x86)\Adobe\Reader 10.0\Reader>AcroRd32.exe **/h** /t "Label.pdf" "HP4000" "HP LaserJet 4100 Series PCL6" "out.pdf"
Related Documentation: https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/Acrobat_SDK_developer_faq.pdf#page=24
You have already tried something different than Acrobat Reader, so my advice is forget about GUI apps and use 3rd party command line tool like RawFilePrinter.exe
private static void ExecuteRawFilePrinter() {
Process process = new Process();
process.StartInfo.FileName = "c:\\Program Files (x86)\\RawFilePrinter\\RawFilePrinter.exe";
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.Arguments = string.Format("-p \"c:\\Users\\Me\\Desktop\\mypdffile.pdf\" \"Canon Printer\"");
process.Start();
process.WaitForExit();
if (process.ExitCode == 0) {
//ok
} else {
//error
}
}
Latest version to download: https://bigdotsoftware.pl/rawfileprinter

Categories