I'm trying to print a PDF file using Process object. And up to certain extent I could print it successfully. But now I want to set printer properties.. like no of copies, Paper size etc. But I don't see any property to set these values.
I'm using following code to print PDFs
string fileName = "";
string arguments = "";
string verbToUse = "";
int i = 0;
ProcessStartInfo startInfo = new ProcessStartInfo();
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.InitialDirectory = "c:\\";
openFileDialog1.Filter = "pdf files (*.pdf)|*.pdf|All files (*.*)|*.*";
openFileDialog1.FilterIndex = 2;
openFileDialog1.RestoreDirectory = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
if ((fileName = openFileDialog1.FileName) != null)
{
startInfo = new ProcessStartInfo(fileName);
if (File.Exists(fileName))
{
i = 0;
foreach (String verb in startInfo.Verbs)
{
// Display the possible verbs.
MessageBox.Show(i.ToString() + ". " + verb);
i++;
}
}
}
//Console.WriteLine("Select the index of the verb.");
string index = "2";
if (Convert.ToInt32(index) < i)
verbToUse = startInfo.Verbs[Convert.ToInt32(index)];
else
return;
startInfo.Verb = verbToUse;
if (verbToUse.ToLower().IndexOf("printto") >= 0)
{
//Printer Name
arguments = #"\\hydfsvt02\HPLaserJ";
startInfo.Arguments = arguments;
}
Process newProcess = new Process();
newProcess.StartInfo = startInfo;
try
{
newProcess.Start();
MessageBox.Show(newProcess.ProcessName + " for file " + fileName + " started successfully with verb " + startInfo.Verb);
}
catch (System.ComponentModel.Win32Exception ex)
{
MessageBox.Show(" Win32Exception caught!");
MessageBox.Show(" Win32 error = " + ex.Message);
}
catch (System.InvalidOperationException)
{
MessageBox.Show("File " + fileName + " started with verb " + verbToUse);
}
}
I have written an application that does batch printing of PDF files.
It's not possible to specify the printer settings that you want to use. It's not even possible if you use the COM interface with the Adobe Standard/Pro versions.
Your options are to either:
Buy a license to a third-party PDF renderer that you can use to convert the PDF to Bitmaps and use the PrintDocument to control the PrinterSettings
Use something like GhostScript to convert the PDF files to BMP files and then use the PrintDocument class to print the BMP files. You can then control the PrinterSettings.
private void startPrintingButton_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (DialogResult.OK == ofd.ShowDialog(this))
{
PrintDocument pdoc = new PrintDocument();
pdoc.DefaultPageSettings.PrinterSettings.PrinterName = "ZDesigner GK420d";
pdoc.DefaultPageSettings.Landscape = true;
pdoc.DefaultPageSettings.PaperSize.Height = 140;
pdoc.DefaultPageSettings.PaperSize.Width = 104;
Print(pdoc.PrinterSettings.PrinterName, ofd.FileName);
}
}
private void Print(string printerName, string fileName)
{
try
{
ProcessStartInfo gsProcessInfo;
Process gsProcess;
gsProcessInfo = new ProcessStartInfo();
gsProcessInfo.Verb = "PrintTo";
gsProcessInfo.WindowStyle = ProcessWindowStyle.Hidden;
gsProcessInfo.FileName = fileName;
gsProcessInfo.Arguments = "\"" + printerName + "\"";
gsProcess = Process.Start(gsProcessInfo);
if (gsProcess.HasExited == false)
{
gsProcess.Kill();
}
gsProcess.EnableRaisingEvents = true;
gsProcess.Close();
}
catch (Exception)
{
}
}
This code will print PDF files as well as adjust the printing settings.
Related
I'm using Mplayer to extrac audio from video via command line. This is the command i use:
mplayer -ao pcm:fast:file=aaa.wav aaa.avi
I copied Mplayer.exe and aaa.avi both on windows drive (C:) and on the root directory of an external hard drive (in my case X).
When i execute from C the dumping start at normal speed (i see the video on real time) and aaa.wav is not created by Mplayer.
When i execute form X the dumping start at fast speed (as requested by the -ao pcm:fast audio driver) and the aaa.wav is correctly created.
I have the same issue in my app, here the code i use to do it:
public static string DumpWav_ConsoleOutput = "";
public static int DumpWav_ProcessID = 0;
Process DumpWav_Process = null;
private void DumpWav(string SourceFileName, string DestinationFileName, bool NeedToCut, TimeSpan Start, TimeSpan End)
{
//cancelliamo le variabili
DumpWav_ConsoleOutput = "";
//Handle della finestra di Media Player
Variables.MediaPlayerHandle = 0;
Variables.MediaPlayerHandle = (int)MediaPlayer.Handle;
Thread thread = new Thread(() => _DumpWav(SourceFileName, DestinationFileName, NeedToCut,Start, End)); //il thread principale di Dump Wav
thread.Start();
while (thread.IsAlive) //aspettiamo il suo completamento
{
Application.DoEvents();
}
var myForm = new Output();
myForm.SetOutputText = Variables.ConsoleOutputMP;
myForm.Show();
Variables.MediaPlayerExit = true;
// ok il processo è terminato
}
private void _DumpWav(string SourceFileName, string DestinationFileName, bool NeedToCut, TimeSpan Start, TimeSpan End)
{
string Output;
Output = RunDumpWav((output) => { }, SourceFileName, DestinationFileName, NeedToCut, Start, End);
}
// Media Player avviato da questa funzione
public string RunDumpWav(Action<string> output, string SourceFileName, string DestinationFileName, bool NeedToCut, TimeSpan Start, TimeSpan End)
{
if (output == null)
throw new ArgumentNullException("output");
string args;
ProcessStartInfo ps = new ProcessStartInfo();
ps.FileName = FindMediaPlayerPath("mplayer.exe");
ps.UseShellExecute = false;
ps.RedirectStandardInput = true;
ps.RedirectStandardError = true;
ps.RedirectStandardOutput = true;
ps.CreateNoWindow = true;
ps.WorkingDirectory = #"x:\";
args = "-wid ";
args += Variables.MediaPlayerHandle;
args += " -ao pcm:fast:file=";
args += DestinationFileName;
if (NeedToCut == true)
{
args += " -ss " + Start + " -endpos " + End;
}
//args += " -vo null -vc null -quiet ";
//-wid will tell MPlayer to show output inisde our panel
args += " " + SourceFileName;
ps.Arguments = args;
using (DumpWav_Process = Process.Start(ps))
using (ManualResetEvent mreOut = new ManualResetEvent(false),
mreErr = new ManualResetEvent(false))
{
DumpWav_Process.OutputDataReceived += (o, e) => { if (e.Data == null) mreOut.Set(); else output(e.Data); };
DumpWav_Process.BeginOutputReadLine();
DumpWav_Process.ErrorDataReceived += (o, e) => { if (e.Data == null) mreErr.Set(); else output(e.Data); }; ;
DumpWav_Process.BeginErrorReadLine();
output = s => DumpWav_ElaborateOutput(s);
DumpWav_ProcessID = DumpWav_Process.Id;
//processMP.StandardInput.Close();
DumpWav_Process.WaitForExit();
mreOut.WaitOne();
mreErr.WaitOne();
//stringa di ritorno (tutto il contenuto della console)
return DumpWav_ConsoleOutput;
}
}
//controlliamo l'output della console
private void DumpWav_ElaborateOutput(string output)
{
Variables.ConsoleOutputMP = Variables.ConsoleOutputMP + output + Environment.NewLine;
if (output.IndexOf("A:") != -1)
{
//some check here
}
}
I recently added this:
ps.WorkingDirectory = #"x:\";
But the result not change, the video speed is not fast and the wav file is not created by Mplayer.
In my app, like the C test, i receive some errors:
[AO PCM] Failed to open aaa.wav for writing!
Failed to initialize audio driver 'pcm:fast:file=aaa.wav'
One more question, when i use mPlayer to encapsulate videos inside my app the process start about one minute after i launched it... maybe concatenate with dumping issue?
Please, any suggestion?
Edit:
I discovered just now: If i start the command prompt with admin rights then also in C Drive Mplayer do the job in the right way...
My app unfortunately don't. I edited the manifest to grant admin rights but it's the same. Somewhere here at stackoverflow i read something about to useshellexecute to true but unfortunately by this way (i need to test anyway) i lose the ability to redirect input/output/error.
I need to find a way to start the process (then the mplayer.exe) from within my app, with admin rights, without use shellexecute...
Edit 2°
I created a simple button with this code:
string args;
//Handle della finestra di Media Player
Variables.MediaPlayerHandle = 0;
Variables.MediaPlayerHandle = (int)MediaPlayer.Handle;
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = FindMediaPlayerPath("mplayer.exe");
//psi.FileName = #"x:\mplayer.exe";
psi.UseShellExecute = true;
psi.CreateNoWindow = true;
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.WorkingDirectory = Environment.CurrentDirectory; ;
psi.Verb = "runas";
args = "-wid ";
args += Variables.MediaPlayerHandle;
args += " -ao pcm:fast:file=";
args += #"x:\aaa.wav";
args += #" x:\aaa.avi";
psi.Arguments = args;
Process.Start(psi);
:-( same result, Mplayer is not able to open audio driver and to save file..
Fail, again.. 3° edit:
I tried using CMD:
private void button2_Click(object sender, EventArgs e)
{
ProcessStartInfo processInfo;
Process process;
Variables.MediaPlayerHandle = 0;
Variables.MediaPlayerHandle = (int)MediaPlayer.Handle;
string args = "";
args = #"x:\mplayer.exe -wid " + Variables.MediaPlayerHandle + #" -ao pcm:fast:file=x:\aaa.wav x:\aaa.avi";
MessageBox.Show(args);
processInfo = new ProcessStartInfo("cmd.exe", "/c " + args);
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = true;
processInfo.Verb = "runas";
process = Process.Start(processInfo);
process.WaitForExit();
MessageBox.Show("terminato");
process.Close();
}
Now i see the first frame of the video and Mplayer freeze...
I'm losing my hope to use mplayer :-(
Finally i solved...
This is the code:
if (output == null)
throw new ArgumentNullException("output");
string args;
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = FindMediaPlayerPath("mplayer.exe");
//psi.FileName = #"x:\mplayer.exe";
psi.UseShellExecute = false;
psi.RedirectStandardInput = true;
psi.RedirectStandardError = true;
psi.RedirectStandardOutput = true;
psi.CreateNoWindow = true;
psi.WorkingDirectory = Path.GetDirectoryName(DestinationFileName);
psi.Verb = "runas";
args = "-wid ";
args += Variables.MediaPlayerHandle;
args += " -ao pcm:fast:file=";
args += Path.GetFileName(DestinationFileName);
if (NeedToCut == true)
{
args += " -ss " + Start + " -endpos " + End;
}
//args += " -vo null -vc null -quiet ";
//-wid will tell MPlayer to show output inisde our panel
args += " " + SourceFileName;
psi.Arguments = args;
As i understand i need to move the Process.WorkingDirectory to the same folder as the destination file (in my case the wav).
Now it rocks :-)
NO need for UAC
NO need for useshellexecute = true
Thanks stanley for your help!
In my application, the student will fill all the details and then will click the submit button.
It will show all the details of the students in studentDetails.aspx page.
In studentDetails.aspx page, there is a Print button.
What I want is that when a student clicks this print button it should show the details of the students in a PDF file format, ready to be printed.
i've tried the following, can anybody help me to come out of this...`
protected void Button1_Click(object sender, EventArgs e)
{
Uri strurl = Request.Url;
string url = strurl.ToString();
string filename = "Test";
HtmlToPdf(url, filename);
}
public static bool HtmlToPdf(string Url, string outputFilename)
{
string filename = ConfigurationManager.AppSettings["ExportFilePath"] + "\\" + outputFilename + ".pdf";
Process p = new System.Diagnostics.Process();
p.StartInfo.Arguments = Url + " " + filename;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.FileName = HttpContext.Current.Server.MapPath(#"C:\Users\$$\Documents\Visual Studio 2008\Projects\santhu") + "wkhtmltopdf.exe";
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit(60000);
int returnCode = p.ExitCode;
p.Close();
return (returnCode == 0 || returnCode == 2);
}
}
You're going to want to leverage something like the iTextSharp library for this. It's a straight forward solution. Consider the following code block:
using (Document doc = new Document(PageSize.A4, 0, 0, 0, 0))
{
using (FileStream stream = new FileStream(targetPath, FileMode.Create))
{
PdfWriter.GetInstance(doc, stream);
doc.Open();
var font = FontFactory.GetFont("Courier", 10);
var paragraph = new Paragraph(sb.ToString(), font);
doc.Add(paragraph);
doc.Close();
}
}
That takes a text file and turns it into a PDF. Now obviously you'll need to modify it for your needs, but you see how simple it is. Plus the library has classes for all of the concepts of a PDF, not just a Paragraph.
I have the app below. I modified it slightly for easier testing for readers here. I notice that when I set the Filename with an extension, e.g. test.txt, the txt extension is removed by the dialog. However I want users to be able to specify an extension, and more importantly I want to be able to set the extension. One way to hack it in I figure is to modify the filter based on the extension I have. Is this the only way?
I am using VS 2010 Express.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.IO;
using System.Windows;
namespace SpeedDating
{
partial class Program
{
[STAThread]
static void Main(string[] args)
{
Form form = new Form();
form.WindowState = FormWindowState.Minimized;
form.ShowInTaskbar = false;
form.TopMost = true;
form.Show();
string filename = "test.txt";
string ext = filename.Substring(filename.LastIndexOf('.'));
SaveFileDialog dialog = new SaveFileDialog();
dialog.Title = "SpeedDating App";
dialog.RestoreDirectory = true;
dialog.CheckFileExists = false;
dialog.CheckPathExists = false;
dialog.SupportMultiDottedExtensions = true;
dialog.AddExtension = false;
dialog.Filter = "All files (*.*)|*.*";
dialog.FileName = DateTime.Now.ToString("yyyyMMdd") + ext;
DialogResult result = dialog.ShowDialog();
if (result == DialogResult.OK && dialog.FileName != "")
{
try
{
FileStream outfs = File.Create(dialog.FileName);
FileStream infs = File.Open(filename, FileMode.Open);
infs.CopyTo(outfs);
infs.Close();
outfs.Close();
MessageBox.Show(form, "Copied file.");
}
catch (NotSupportedException ex)
{
MessageBox.Show(form, "Probably removed the original file.");
}
}
else if (result != DialogResult.Cancel)
{
MessageBox.Show(form, "No path found to write to.");
}
form.Close();
}
}
}
and more importantly I want to be able to set the extension
You can set the .DefaultExt(), .AddExtension(), .Filter(), and .FilterIndex() properties:
string filename = "test.xyz";
SaveFileDialog dialog = new SaveFileDialog();
dialog.Title = "SpeedDating App";
dialog.RestoreDirectory = true;
dialog.CheckFileExists = false;
dialog.CheckPathExists = false;
dialog.SupportMultiDottedExtensions = true;
dialog.Filter = "All files (*.*)|*.*";
dialog.DefaultExt = System.IO.Path.GetExtension(filename);
if (dialog.DefaultExt.Length > 0)
{
dialog.AddExtension = true;
dialog.Filter = dialog.DefaultExt + " files (*." + dialog.DefaultExt + ")|*." + dialog.DefaultExt + "|" + dialog.Filter;
dialog.FilterIndex = 0;
}
dialog.FileName = DateTime.Now.ToString("yyyyMMdd");
DialogResult result = dialog.ShowDialog();
if (result == DialogResult.OK && dialog.FileName != "")
{
Console.WriteLine(dialog.FileName);
}
*Note that if the option to display "File Extensions" is turned OFF in File Explorer, then the dialog will also hide the extension...BUT the above setup will add the set extension to the .FileName() value returned by the dialog.
I'm trying to use the following C# code to compile Java using javac:
Process p = new Process();
p.StartInfo.FileName = "javac";
Directory.CreateDirectory(Application.StartupPath + #"/TempJava");
p.StartInfo.Arguments = "-d "Application.StartupPath + #"/TempJava" + files;
p.Start();
"files" represents a string variable containing the name(s) of the *.java files.
All in all, I want to create a new folder, and then take the Java files (from where ever they may be located) and compile it into a class file(s) in TempJava.
For some reason, the code doesn't work, no errors, no warnings, but when I run it and check TempJava, there's no files in it.
Just because your child process ends with a possible error, it doesn't mean your parent process must be aware of it.
Inspect the process' exit code and standard output stream, and especially the standard error stream. Your answer lies in there...
here i have 2 buttons run and compile here is some code to help.
private void comp_Click(object sender, EventArgs e)
{
string text = "javac " + label1.Text + file + "#pause" + "#stop";
text = text.Replace("#", System.Environment.NewLine);
File.WriteAllText(label1.Text + "Compile.bat", text);
Process proc = null;
try
{
proc = new Process();
proc.StartInfo.FileName = label1.Text + "Compile.bat";
proc.StartInfo.CreateNoWindow = false;
proc.Start();
proc.WaitForExit();
}
catch
{
}
}
private void runp_Click(object sender, EventArgs e)
{
string news = file.Remove(file.Length - 5);
string text = "java " + news + "#pause";
text = text.Replace("#", System.Environment.NewLine);
File.WriteAllText(label1.Text + "Run.bat", text);
Process proc = null;
try
{
proc = new Process();
proc.StartInfo.FileName = label1.Text + "Run.bat";
proc.StartInfo.WorkingDirectory = label1.Text.Remove(label1.Text.Length - 1);
proc.StartInfo.CreateNoWindow = true;
proc.Start();
proc.WaitForExit();
}
catch
{
}
}
all i really do is create a batch and run it using c#.
I use this method to compile C++ file in VS. But even i provide the correct file it returns false. Can any one help me...
This is class called CL
class CL
{
private const string clexe = #"cl.exe";
private const string exe = "Test.exe", file = "test.cpp";
private string args;
public CL(String[] args)
{
this.args = String.Join(" ", args);
this.args += (args.Length > 0 ? " " : "") + "/Fe" + exe + " " + file;
}
public Boolean Compile(String content, ref string errors)
{
if (File.Exists(exe))
File.Delete(exe);
if (File.Exists(file))
File.Delete(file);
File.WriteAllText(file, content);
Process proc = new Process();
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.FileName = clexe;
proc.StartInfo.Arguments = this.args;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
//errors += proc.StandardError.ReadToEnd();
errors += proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
bool success = File.Exists(exe);
return success;
}
}
This is my button click event
private void button1_Click(object sender, EventArgs e)
{
string content = "#include <stdio.h>\nmain(){\nprintf(\"Hello world\");\n}\n";
string errors = "";
CL k = new CL(new string[] { });
if (k.Compile(content, ref errors))
Console.WriteLine("Success!");
else
MessageBox.Show("Errors are : ", errors);
}
In your Visual Studio installation folder there should be the following path:
VC\bin\x86_amd64\1033\1033
There should be a clui.dll in this path. Copy it to the parent folder (VC\bin\x86_amd64\1033). This should solve your problem.
I took the solution from http://connect.microsoft.com/VisualStudio/feedback/details/108528/command-line-issue-when-building-for-64bit-in-32bit-with-cl-exe:
Maybe it is not relevant, but I think you miss a space in your command line...
this.args += (args.Length > 0 ? " " : "") + "/Fe" + exe + " " + file;
right after the "/Fe"