Open a PDF with Open Parameters Using C# / VB.NET - c#

The accepted answer to this question regarding how to open a PDF to a specific page using C# is, in summary:
Process myProcess = new Process();
myProcess.StartInfo.FileName = "acroRd32.exe"; //not the full application path
myProcess.StartInfo.Arguments = "/A \"page=2=OpenActions\" C:\\example.pdf";
myProcess.Start();
However, this answer appears to be incomplete. It works great if Adobe Reader (acroRd32.exe) is not already running, but if Reader is running, this code won't do anything (at least on my Windows 8.1 PC). So, how can you open in PDF to a specified page using C# (or VB.NET) regardless of whether Adobe Reader is already running?

Turns out the trick is to add the "/n" switch to the arguments string just before the PDF path as follows:
myProcess.StartInfo.Arguments = String.Format("/A ""zoom={0}&page={1}=OpenActions"" /n ""{2}", strZoom, strPage, strPath)
According to the Acrobat developer FAQ, the /n switch "Launches a separate instance of Acrobat or Adobe Reader, even if one is currently open." I cannot imagine a case where you wouldn't want to use this switch (when opening a PDF as described in the OP), so it is surprising that there is little mention of this switch in the dozens of proposed solutions on this topic.

Related

How to programatically send openoffice writer odt file to printer from C# Windows Forms Application

I'd like to send an OpenOffice writer document to the default printer from within a C# WinForms application. The purpose is to print customer receipts. I plan on opening a prepared OpenOffice file, substitute dynamic customer information and then print the modified document. It is important that OO not necessarily be installed so solutions which depend on OO or open up an OO prompt won't work. Any suggestions would be appreciated.
I too use open office for printing customer generated invoices, I do so in bulk and below is the method that I use.
What you are seeking is achievable by using "ProcessStartInfo" from the Systems.Diagnostics namespace found here:
https://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo(v=vs.110).aspx
the important part is ensuring you have set "CreateNoWindow" to true as well as settings the "WindowStyle" to "ProcessWindowStyle.Hidden".
Simply pass in the location of the file to print, and ensure you include the file extension after the location. I use this snippet regularly so if you have any problems just let me know.
void printDoc(String fileLocation) {
ProcessStartInfo info = new ProcessStartInfo(fileLocation);
info.Verb = "print";
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(info);
}

Difference in behavior between ProcessInfo/Process.Start and the Run prompt

I'm trying to open a PDF from within my application. I've gone through several iterations for this and have resolved that my only remaining option is to just open Adobe Reader passing the location of the PDF as an argument. The libraries I've looked at don't support what I need (rendering form fields) nor does the Telerik PDF control. So, I've absolutely explored the buy option over build.
Anyway, this works fine from the Run prompt like so:
"C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe" "C:\Users\Foo\AppData\Local\Temp\Bar.pdf"
However, from code, doing the following does NOT work:
ProcessStartInfo info = new ProcessStartInfo(#"C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe", location);
Process.Start(info);
Using Process.Start, I can see the Adobe process in my Task Manager list as a background process but there is no UI while it works flawlessly from Run where it shows up under App and gives the UI as I'd expect.
I don't see a way to force a UI to appear. The MainWindowHandle is 0, the WindowStyle is set to Normal, and CreateNoWindow is false.
Other things I've tried is setting the EnvironmentVariables collection manually and turning off shell execution. I've also tried loading the user profile into the process to no effect.
What do I need to do do here?
I ended up getting around this situation entirely. I used iTextSharp to flatten the PDF and from there my normal tooling for rendering PDFs worked fine. Thankfully, this has other benefits for my needs as well.
I still couldn't solve the different in behavior I described. I was about to go down the path of Win32 via ShellExecute to leave a "where I left off" note.
*.Pdf files are always opened using Adobe reader, unless you have installed some other pdf reader. So don't call the adobe application, just call the file using Process.start(#"file location and name.pdf"). Then the file will be opened in the default pdf reader.
You'll need a system reference using System.Diagnostics;
And here's another thing, above you have used Process.Start() to give the file location but remember this won't help if the application mentioned doesn't take any arguments/instructions.
Process.Start(#"application.exe", "instructions to application.exe")

Print PDF and reading the error output of the Process

Well, my objective is to print a PDF file without asking for user confirmation.I can't force my users to use a specific PDF reader (such as Adobe Acrobat or Foxit) and need to print the file without any user interaction.
My current code is the following:
String strFile = "pdf_file.pdf";
String strPrinter = "Printer Name";
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = strFile;
p.StartInfo.Arguments = strPrinter;
p.StartInfo.Verb = "PrintTo";
p.StartInfo.CreateNoWindow = true;
p.Start();
p.CloseMainWindow();
I have some code to kill the process if it don't exit, but it doesn't matter now.
This code works mostly well, but i can't get the error messages that occur in the process.
The try catch block won't help in this case, because the error occur in the process "p", not in the main process.
Searching the net i found out that to recover the errors i need to set the following:
p.StartInfo.RedirectStandardError = true;
p.StartInfo.UseShellExecute = false;
// Start process, kill it, etc...
String s = p.StandardError.ReadToEnd();
But applying this code gives me another error: the file is not a valid win32 application.
Obviously, the file I'm oppening is a PDF file, not a EXE.
Anyone knows another way to recover the errors that occur in the process?
Such as the printer is not found, etc...
If I understood it right, you are trying to print a PDF file using the default PDF reader installed in the client machine.
As you said, this code is trying to actually run a .pdf file. You could use a C# PDF library, but I dont know how it'll send the raw PDF data to the printer, so I would try using a PDF command line tool, put it in the bin/Release folder of the project (and also bin/Debug, for testing purposes) and then call it using a command line.
If you want it to be totally transparent and PDF-Reader independent, maybe you should try it. In the command line, you explicitly tell what executable you want to run, so it wont make Adobe Acrobat Reader pop up in the screen, and the user won't freak out =D
Here is an example of PDF printer:
http://pdfbox.apache.org/commandline/#printPDF
The command line is: java -jar pdfbox-app-x.y.z.jar PrintPDF [OPTIONS] <inputfile>
It needs Java to run, if this is not a problem, you can try it. You could also search for a native or .NET managed solution, I think you got the idea.
Good luck!

PDF Printing happens in random order

I am using Foxit Reader (a PDF Reader) and passing command line arguments to print a pdf pro-grammatically. I understand that we cannot specify the number of copies through command line as from this discussion.
I am developing a win-forms desktop application and for printing multiple copies of PDF document I am using the below code
string foxitReaderInstalledPath = GetFoxitReaderInstalledPath();
while (noOfCopies > 0)
{
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();
noOfCopies = noOfCopies - 1;
}
Issue happens when multiple users are giving muliple copies of print to the same printer. The issue is the printed documents gets mixed up in the order in which they get printed. Anyone please let me know how I can avoid this issue?
Many thanks.
You can't avoid this client-side...
IF you really want to avoid it the "client" app which is used by the users has to just send the file to some "centralized server process" with all relevant params... this "centralized process" can then "serialize" the printing so it occurs in correct order...
BUT if the printer you are printing to is accessible from the users systems then it could still happen that a user sends something to the printer (like an image or word document...) which will be printed and disturbing the order a bit...
I think it would make much more sense if you described what your goal is... perhaps there is some better way to solve all this... are you implementing a print server ?
EDIT - as per comment:
Put the location for the PDF files on a network share... and run your printing code on the same machine which provides the share... ideally the printer is directly connected to that machine... this should provide enough performance and since it is only one central application accessing the printer it should work fine...
I would strongly recommend the use of a PDF library or Acrobat reader so that the printing can use a parameter for NumberOfCopies !
EDIT 2 - as per comment:
Some PDF Libraries:
.NET library to print PDF files
http://www.gnostice.com/PDFOne_dot_NET.asp
http://www.gdpicture.com/products/dotnet/plugins/pdf-plugin.php
http://itextpdf.com/

C# System.Diagnostics.Process verb issue

I have a Windows Application written in C# VS 2008. The purpose of this application is to convert any file to PDF files. I have found code that works on converting the files however there is a small issue that I am coming across.
First here is the code:
private void PrintToAdobePDF(string strInputFilePath)
{
ProcessStartInfo pProcInfo = new ProcessStartInfo();
bool blResult;
blResult = SetDefaultPrinter(D2P_Adobe_Printer);
if (blResult)
{
pProcInfo.FileName = strInputFilePath;
pProcInfo.Verb = "Print";
pProcInfo.CreateNoWindow = true;
pProcInfo.WindowStyle = ProcessWindowStyle.Hidden;
Process pProc = Process.Start(pProcInfo);
pProc.WaitForExit(1000);
pProc.CloseMainWindow();
pProc.Close();
}
The issue I am having is that when the Process.Start() method is invoke it is running with TWO verbs instead of the one verb I specified ("Print"). It is running "Open" and "PrintTo" which is making the application that the original file is derived from open up and hang the application (i.e. jpg opens the Windows Fax and Picture Viewer).
My question is how do I just use the "Print" verb within the Process.Start() method?
Thank you in advance
Have you tried researching if it's possible to execute Adobe Reader with a command line parameter that accomplishes the same thing? Relying on the shell is iffy sometimes.
What are sending in for strInputFilePath? The documentation says to only send the filename so if you are sending the whole path that could be causing the issue.
No, sending the filename without the extension will fail.
Ultimately using System.Diagnostics.Process to print any arbitrary file is going to be unpredictable at best. It's all up to how your operating system handles each type of file, and whether or not your registry is properly configured to handle that file.
I'd guess that printing .doc files in this manner probably works OK, while other file types may not work so well.
In my opinion, you should find some constraint about the kinds of files you'll allow to "automagically" print, and build working solutions per type of file. Otherwise, you'll find a lot of unpredictable behavior.

Categories