Error while trying to print the pdf file - c#

I was trying to print a pdf document in the background using a console application. I used the process for doing it. The console application sends the pdf file to the printer, But the adobe reader that is opened in the background in minimized mode is throwing the following error "There was an error opening this document. This file cannot be found". As a result of this while printing multiple times, I was not able to kill the process. Is there any possibility of getting rid of this error?
My requirement is to print the pdf file using process and while doing that the pdf file must be opened in the minimized mode and once done printing the reader needs to be closed automatically. I have tried the following code, but still throws the error..
string file = "D:\\hat.pdf";
PrinterSettings ps = new PrinterSettings();
string printer = ps.PrinterName;
Process.Start(Registry.LocalMachine.OpenSubKe(#"SOFTWARE\Microsoft\Windows\CurrentVersion"+#"\App Paths\AcroRd32.exe").GetValue("").ToString(),string.Format("/h /t \"{0}\" \"{1}\"", file, printer));

since you want to have Acrobat reader open in the background when you want to print the document, you could use something like:
private static void RunExecutable(string executable, string arguments)
{
ProcessStartInfo starter = new ProcessStartInfo(executable, arguments);
starter.CreateNoWindow = true;
starter.RedirectStandardOutput = true;
starter.UseShellExecute = false;
Process process = new Process();
process.StartInfo = starter;
process.Start();
StringBuilder buffer = new StringBuilder();
using (StreamReader reader = process.StandardOutput)
{
string line = reader.ReadLine();
while (line != null)
{
buffer.Append(line);
buffer.Append(Environment.NewLine);
line = reader.ReadLine();
Thread.Sleep(100);
}
}
if (process.ExitCode != 0)
{
throw new Exception(string.Format(#"""{0}"" exited with ExitCode {1}. Output: {2}",
executable, process.ExitCode, buffer.ToString());
}
}
You can print your PDF by incorporating the above code into your project and using it as follows:
string pathToExecutable = "c:\...\acrord32.exe";
RunExecutable(pathToExecutable, #"/t ""mytest.pdf"" ""My Windows PrinterName""");
this code was taken from http://aspalliance.com/514_CodeSnip_Printing_PDF_from_NET.all
If you do not need to have Acrobat Reader open in the background, and just print the pdf like any other document, you can have a look at the PrintDocument class:
http://msdn.microsoft.com/en-us/library/system.drawing.printing.printdocument.print.aspx

Related

Cannot open the output file generated from running an exe

I have to run an exe file through C# code and open the output file generated by the exe to do some pre-processing.
The output file is generated successfully by running the exe. But when I try to open the output file at the same run, I am getting File Not Found Exception but when I run the program again, the code reads my output file and I am able to do the pre-processing.
private static void launchExe()
{
string filename = Path.Combine("//myPathToExe");
string cParams = "argumentsToExe";
var proc = System.Diagnostics.Process.Start(filename, cParams);
proc.Close();
}
I now need to open the output file generated by the exe.
private static void openOutputFile()
{
StreamReader streamReader = new StreamReader("//PathToOutputFile");
string content = streamReader.ReadToEnd();
/*
* Pre Processing Code
*/
}
At this stage I am getting File Not Found Exception but I have the output file generated in the specified path.
Kindly help me with this issue.
Don't close your app, but WaitForExit.
string filename = Path.Combine("//myPathToExe");
string cParams = "argumentsToExe";
var proc = System.Diagnostics.Process.Start(filename, cParams);
proc.WaitForExit();

Load standart output and parse it to Image

I have graphviz dot.exe file that I call with parameter -Tpng (output type is png, but I don't care if it is in png, bmp, or any other). I start it in C# code:
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = path;
psi.UseShellExecute = false;
psi.Arguments = "-Tpng";
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.CreateNoWindow = true;
Process p = Process.Start(psi);
Then, I write input
p.StandardInput.WriteLine(input);
input is defined before, it's a string. Input is valid, tested manually.
Then, I need to read output that graphviz prints into standart output and parse it to Image.
I've tried to read memory stream, but I was either unable to read it, or, after reading, the memory stream was locked (threw exception when tried Image.FromStream(myMemoryStream);).
I was able to load output to string
string output = "";
while (true)
{
string newOutput = p.StandardOutput.ReadLine();
output += newOutput;
if (newOutput == String.Empty)
break;
}
I've tried to parse this string as described in this answer, but it threw exception (string is not valid).
How can I get Image from the dot.exe output?
From the comments it seems the program is expecting the StandardInput to be finished before returning the content. Close the StandardInput to achieve it:
p.StandardInput.WriteLine(input);
p.StandardInput.BaseStream.Close();

How to monitor a logfile that seems to be open all the time (much like notepad++ does)?

I'm trying to build a small program to monitor my pfirewall.log, but I can't seem to open it.
I found quite many (simple) answers, that all kinda say
// use FilesystemWatcher
// open FileStream
// read from last position to end
// output new lines
The problem here is: The file seems to always be opened by another process already. I guess that's the windows process writing to the file, since it's getting written to all the time, as Notepad++ shows me.
Which means, Notepad++ can for some reason do what I can not: Read the file despite it being opened already.
I initialize my monitor in the constructor:
public FirewallLogMonitor(string path)
{
if (!File.Exists(path))
throw new FileNotFoundException("Logfile not found");
this.file = path;
this.lastPosition = 0;
this.monitor = new FileSystemWatcher(Path.GetDirectoryName(path), Path.GetFileName(path));
this.monitor.NotifyFilter = NotifyFilters.Size;
}
And try to read the file on monitor.Changed event:
private void LogFileChanged(object sender, FileSystemEventArgs e)
{
using (FileStream stream = new FileStream(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.Read))
using (StreamReader reader = new StreamReader(stream))
{
stream.Seek(this.lastPosition, SeekOrigin.Begin);
var newLines = reader.ReadToEnd();
this.lastPosition = stream.Length;
var filteredLines = filterLines(newLines);
if (filteredLines.Count > 0)
NewLinesAvailable(this, filteredLines);
}
}
It always throws the IOException on new FileStream(...) to tell me the file is already in use.
Since Notepad++ does it, there has to be a way I can do it too, right?
**Edit: ** A button does this:
public void StartLogging()
{
this.IsRunning = true;
this.monitor.Changed += LogFileChanged;
this.monitor.EnableRaisingEvents = true;
}
**Edit2: ** This is not a duplicate of FileMode and FileAccess and IOException: The process cannot access the file 'filename' because it is being used by another process, since that one assumes I have control over the writing process. Will try the other suggestions, and report back with results.
If i understand your question you can use the notepad++ itself with a plugin to monitor you need to go to:
plugins -> Document Moniter -> Start to monitor
if you dont have this plugin you can download it here:
http://sourceforge.net/projects/npp-plugins/files/DocMonitor/

redirect printer output to C# application, using redmon

I'm trying to intercept the content from a redirect port (Redmon) to a C# application so I can process it. Right now I'm just trying to figure out how to pass the output into my app.. I thought I could just input it through std input, but its not working. In a coomand line I can pipe text into my application and it works, but if I try to print through a redmon port, my application doesn't seem to take the input. I set up Redmon to let my application handle the output. Here's my code and a screen shot of the printer port settings.
namespace titoprint
{
class Program
{
static void Main()
{
int result;
while ((result = Console.Read()) != -1)
{
Console.WriteLine("{0} = {1} ", result, (char)result);
}
Console.WriteLine("in console");
MessageBox.Show("ok done!");
Console.ReadLine();
}
}
}
`Port settings
I;m only tryint to pass text to the application also. So so the process i'm using is winprint and set to text.
Thanks
You can read like this:
Stream content = Console.OpenStandardInput();
using (BinaryReader standardInputReader = new BinaryReader(content))
{
using (FileStream standardInputFile = new FileStream(standardInputFilename, FileMode.Create, FileAccess.ReadWrite))
{
standardInputReader.BaseStream.CopyTo(standardInputFile);
}
}
Then you can convert to PDF:
String[] ghostScriptArguments = { "-dBATCH", "-dNOPAUSE", "-dSAFER", "-sDEVICE=pdfwrite",String.Format("-sOutputFile={0}", outputFilename), standardInputFilename };

Print existing PDF (or other files) in C#

From an application I'm building I need to print existing PDFs (created by another app).
How can I do this in C# and provide a mechanism so the user can select a different printer or other properties.
I've looked at the PrintDialog but not sure what file it is attempting to print, if any, b/c the output is always a blank page. Maybe I'm just missing something there.
Do I need to use "iTextSharp" (as suggested else where)? That seems odd to me since I can "send the the file to the printer" I just don't have any nice dialog before hand to set the printer etc. and I don't really want to write a printing dialog from the ground up but it seems like a lot of examples I found by searching did just that.
Any advice, examples or sample code would be great!
Also if PDF is the issue the files could be created by the other app in a diff format such as bitmap or png if that makes things easier.
Display a little dialog with a combobox that has its Items set to the string collection returned by PrinterSettings.InstalledPrinters.
If you can make it a requirement that GSView be installed on the machine, you can then silently print the PDF. It's a little slow and roundabout but at least you don't have to pop up Acrobat.
Here's some code I use to print out some PDFs that I get back from a UPS Web service:
private void PrintFormPdfData(byte[] formPdfData)
{
string tempFile;
tempFile = Path.GetTempFileName();
using (FileStream fs = new FileStream(tempFile, FileMode.Create))
{
fs.Write(formPdfData, 0, formPdfData.Length);
fs.Flush();
}
try
{
string gsArguments;
string gsLocation;
ProcessStartInfo gsProcessInfo;
Process gsProcess;
gsArguments = string.Format("-grey -noquery -printer \"HP LaserJet 5M\" \"{0}\"", tempFile);
gsLocation = #"C:\Program Files\Ghostgum\gsview\gsprint.exe";
gsProcessInfo = new ProcessStartInfo();
gsProcessInfo.WindowStyle = ProcessWindowStyle.Hidden;
gsProcessInfo.FileName = gsLocation;
gsProcessInfo.Arguments = gsArguments;
gsProcess = Process.Start(gsProcessInfo);
gsProcess.WaitForExit();
}
finally
{
File.Delete(tempFile);
}
}
As you can see, it takes the PDF data as a byte array, writes it to a temp file, and launches gsprint.exe to print the file silently to the named printer ("HP Laserjet 5M"). You could replace the printer name with whatever the user chose in your dialog box.
Printing a PNG or GIF would be much easier -- just extend the PrintDocument class and use the normal print dialog provided by Windows Forms.
Good luck!
Although this is VB you can easily translate it. By the way Adobe does not pop up, it only prints the pdf and then goes away.
''' <summary>
''' Start Adobe Process to print document
''' </summary>
''' <param name="p"></param>
''' <remarks></remarks>
Private Function printDoc(ByVal p As PrintObj) As PrintObj
Dim myProcess As New Process()
Dim myProcessStartInfo As New ProcessStartInfo(adobePath)
Dim errMsg As String = String.Empty
Dim outFile As String = String.Empty
myProcessStartInfo.UseShellExecute = False
myProcessStartInfo.RedirectStandardOutput = True
myProcessStartInfo.RedirectStandardError = True
Try
If canIprintFile(p.sourceFolder & p.sourceFileName) Then
isAdobeRunning(p)'Make sure Adobe is not running; wait till it's done
Try
myProcessStartInfo.Arguments = " /t " & """" & p.sourceFolder & p.sourceFileName & """" & " " & """" & p.destination & """"
myProcess.StartInfo = myProcessStartInfo
myProcess.Start()
myProcess.CloseMainWindow()
isAdobeRunning(p)
myProcess.Dispose()
Catch ex As Exception
End Try
p.result = "OK"
Else
p.result = "The file that the Document Printer is tryng to print is missing."
sendMailNotification("The file that the Document Printer is tryng to print" & vbCrLf & _
"is missing. The file in question is: " & vbCrLf & _
p.sourceFolder & p.sourceFileName, p)
End If
Catch ex As Exception
p.result = ex.Message
sendMailNotification(ex.Message, p)
Finally
myProcess.Dispose()
End Try
Return p
End Function
You will need Acrobat or some other application that can print the PDF. From there you P/Invoke to ShellExecute to print the document.
You could also use PDFsharp - it's an open source library for creating and manipulating PDFs.
http://www.pdfsharp.net/
I'm doing the same thing for my project and it worked for me
See if it can help you...
Process p = new Process();
p.EnableRaisingEvents = true; //Important line of code
p.StartInfo = new ProcessStartInfo()
{
CreateNoWindow = true,
Verb = "print",
FileName = file,
Arguments = "/d:"+printDialog1.PrinterSettings.PrinterName
};
try
{
p.Start();
}
catch
{
/* your fallback code */
}
You can also play with different options of windows
PRINT command to get desired output...Reference link
After much research and googling about this task Microsoft has released a great KB to print a pdf without any other applications necessary. No need to call adobe or ghostprint. It can print without saving a file to the disk makes life very easy.
http://support2.microsoft.com/?kbid=322091

Categories