I looked around for a while and didn't find many promising articles on the question I have.
I am attempting to write a program that will query users for the path to a file using the openFileDialog and saving the output to a string in C#. What I want to do with it, is use said path in a command script that will copy the file to another part of the computer for use by the program that I am writing.
I am pretty new to C#, so the dummy version, if possible, would be appreciated. I so far understand that I have to set up a new process to run batch commands in general, but I never could find good examples of how to pass C# strings to the batch script.
Thanks
Why not just use .NET's built in Copy method? You can use a Backgroundworker or a Task to make this occur on a different thread, also.
If you must spin up a separate process, then you can use Process.Start with ProcessInfo set up to the path and pass the arguments in that way.
If your script is long, I would use a StringBuilder then write the string to a file:
// set srcFilename and xcopyOptions (like /Y, for example)
var sb = new StringBuilder();
sb.Append( "XCOPY " )
.Append( xcopyOptions )
.Append( " " )
.Append( srcFilename )
.Append( " " )
.AppendLine( dstDir );
// repeat for as many copy commands as you want
// ...
File.WriteAllText( scriptFilename, sb.ToString() );
In addition to already available post, if you really want to use a batch, to pass a variable to it is the same like a pass arguments to an executable.
instance process , where "ececutable" is a batch file
assign arguments, which will be passed like a parameters to the variables of the batch.
Process thisProcess = new Process();
thisProcess.StartInfo.CreateNoWindow = true; //NO NEED OF WINDOW
thisProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
thisProcess.StartInfo.WorkingDirectory = #"DirectoryOfTheBacth";
thisProcess.StartInfo.FileName = "BatchFileName";
thisProcess.StartInfo.Arguments = "parameters";
thisProcess.StartInfo.UseShellExecute = false; //NO SHELL EXECUTE
thisProcess.StartInfo.RedirectStandardOutput = true; //STDO REDIRECTION, SO WE CAN READ WHAT IS HAPPENNING
thisProcess.Start(); // FINALLY, START PROCESS
How to pass parameter from C# to a batch file?
Related
Has anyone ever created a PDF document from a TeX document using pdflatex.exe in their C#/WPF application? I have my TeX document and I want to convert it to PDF and display it within the application, however, I'm unsure how to go about doing this and there's virtually nothing that I can find online about doing something like this. Does anyone know what the best way to do something like this is (convert a TeX document to PDF via pdflatex.exe within a C# application)?
Thanks a lot!
Here's the code I used. It assumes the source is in the same folder as the executable, and includes running BibTeX if you need it (just exclude the second process if needed).
string filename = "<your LaTeX source file>.tex";
Process p1 = new Process();
p1.StartInfo.FileName = "<your path to>\pdflatex.exe";
p1.StartInfo.Arguments = filename;
p1.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p1.StartInfo.RedirectStandardOutput = true;
p1.StartInfo.UseShellExecute = false;
Process p2 = new Process();
p2.StartInfo.FileName = "<your path to>\bibtex.exe";
p2.StartInfo.Arguments = Path.GetFileNameWithoutExtension(filename);
p2.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p2.StartInfo.RedirectStandardOutput = true;
p2.StartInfo.UseShellExecute = false;
p1.Start();
var output = p1.StandardOutput.ReadToEnd();
p1.WaitForExit();
p2.Start();
output = p2.StandardOutput.ReadToEnd();
p2.WaitForExit();
p1.Start();
output = p1.StandardOutput.ReadToEnd();
p1.WaitForExit();
p1.Start();
output = p1.StandardOutput.ReadToEnd();
p1.WaitForExit();
Yes, this could be cleaned up a little, and certainly without the call to BibTeX could just be called in a loop (3 times is the recommended number to make sure all the references are correct). Also, there's no exception handling, so you might want to add try / catch blocks around the process calls, etc.
I have never done that, but this is perfectly possible. You'll need to use System.Diagnostics.Process class to run pdflatex.exe
The rest is about choosing the way this should run. You probably have some options here:
If pdflatex supports writing output to "standard output" you can intercept that and do with the content whatever you want.
Another option is using some temporary folder to write the file to and subscribing to notifications about folder changes (asynchronous, you can run multiple instances of pdflatex) or simply waiting for the process to finish (synchronous, you can run only one instance of pdflatex at a time).
I'm developing a c# application to automatically execute sqlplus. I would like to find a way to use the set lines, set pages.. and spool command to create an output file of the proper format and layout.
here is a code i used to run sqlplus from cmd using c#
ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.FileName = "sqlplus.exe";
processInfo.Arguments = "username/password#database #scriptFilePath";
Process process = Process.Start(processInfo);
how can i incorporate and use those commands i mentioned above? Help!
Can't you just set the ProcessStartInfo.RedirectStandardInput property to true and then write to Process.StandardInput?
How about:
Bring the window to front
Send the keys
Like following:
Process sqlplus = Process.Start(processInfo);
sqlplus.WaitForInputIdle();
IntPtr hWindow = sqlplus.MainWindowHandle;
ShowWindow(hWindow, 1 /*toggle*/);
SendKeys.SendWait("SELECT * FROM...");
SendKeys.SendWait("{Enter}");
I am trying to launch the default application registered for an extension specifying an additional argument:
ProcessStartInfo p = new ProcessStartInfo();
p.Arguments = "myargument";
p.FileName = "file.ext";
Process.Start(p);
The application starts correctly opening the specified file.
The problem is that it is getting just one parameter (the name of the file), totally ignoring the additional "Arguments".
Is it possible to do what I want?
Am I doing something wrong?
Thanks in advance for any help,
Paolo
I believe this is expected. Behind the scenes, Windows is finding the default application in the registry and creating a new process and passing your file name to it. I get the same behavior if I go to a command prompt and type "filename.ext argument", that my arguments are not passed to the application.
What you probably need to do is find the default application yourself by looking in the registry. Then you can start that process with arguments, instead of trying to start by filetype association. There is an answer here on how to find the default application in the registry:
Finding the default application for opening a particular file type on Windows
what exactly is your "argument", does it have spaces, backslash, etc?
Process process = new Process();
process.StartInfo.FileName = #"C:\process.exe";
process.StartInfo.Arguments = #"-r -d something else";
process.StartInfo.CreateNoWindow = false;
process.StartInfo.UseShellExecute = false;
process.Start();
Is there any reason why you cant start the app, then use the extension and arguments in your arguments?
I think an easier method is using the cmd command
void LaunchAssociatedProgram(string filename) {
Process.Start( #"cmd.exe", "/C start "+ filename );
}
EDIT:
I don't know if it works with arguments, but it is what I was looking for to launch an associated program...
Some sample code:
var psi = new ProcessStartInfo();
psi.FileName = "path to update.exe";
psi.Arguments = "arguments for update.exe";
psi.Verb = "runas";
var process = new Process();
process.StartInfo = psi;
process.Start();
process.WaitForExit();
Ref: 0xA3.
Programmatically in code what type of objects if possible could you pass into the '.Arguments' property? Typically you can pass an int or a string type. I want to know if you could pass in a more complicated type like a DirectoryInfo[] or a FileInfo[]? Would anyone know if this is possible? If not i'll have to come up with something else?
Why? I am trying to remove some problem code from a very large background worker and the only solution is to pass the data I require into a process that will handle the work I need doing in a completey different process. Problem this problem code always throws up on permissions - permissions the app does not have.
Serialize the data then you can "pipe" the resulting string into the other process's standard input. See example of "Process.StandardInput Property" help topic at http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardinput.aspx
Serialize the data, store into a file then have other process read this file, passing the path to the file in Arguments.
- Allocate the object into global memory then pass the resulting IntPtr, in Arguments, to the other process.
The arguments are exactly what you'd type (with leading and trailing quotes), if you were running the .exe from the command prompt.
Use strings.
As defined the Arguments property is of type string so you could only pass space delimited arguments to the process the same way you would when calling it at the command line.
No, this isn't possible.
You should consider making a new AppDomain in your existing process.
I'd like to be able to use FFmpeg to convert a video file from within my C# program. I know I can just call a shell command, but is there a better way?
The issue with invoking a command via the shell, is I'm not sure you could do things like a progress bar, etc... or could you?
If there isn't a way, can anyone suggest the best way to layout some framework for executing shell commands. Passing one big long string is very cumbersome atm.
You can easily implement a progress bar if running ffmpeg. The output of ffmpeg while running is something like:
frame= 3366 fps=465 q=31.0 Lsize= 6474kB time=140.35 bitrate= 377.9kbits/s
And it is refreshed ~twice per second. You can parse that line and get the data you need to display the progress. When you run in the command line, you only see one line being updated all the time, but what ffmpeg does is to write the line followed by \r. That's why you don't see multiple lines. However, when using StreamReader.ReadLine() on the error output of the program, you get one line for every update.
Sample code to read the output follows. You would have to ignore any line that does not begins with 'frame', perhaps use BeginErrorReadLine()+ErrorDataReceived if you want reading lines to be asynchronous, etc., but you get the idea (I've actually tested it):
using System;
using System.Diagnostics;
using System.IO;
class Test {
static void Main (string [] args)
{
Process proc = new Process ();
proc.StartInfo.FileName = "ffmpeg";
proc.StartInfo.Arguments = "-i " + args [0] + " " + args [1];
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.UseShellExecute = false;
if (!proc.Start ()) {
Console.WriteLine ("Error starting");
return;
}
StreamReader reader = proc.StandardError;
string line;
while ((line = reader.ReadLine ()) != null) {
Console.WriteLine (line);
}
proc.Close ();
}
}
There's a wrapper library over FFmpeg for .NET.
I have found this post few weeks ago when I was looking for answer for my problem.
I tried to start ffmpeg process and pass arguments to it but it take sooo long to do everything. At this point I use Xabe.FFmpeg as it doing this out of the box and don't have to worry about ffmpeg executables because have feature to download latest version.
bool conversionResult = await new Conversion().SetInput(Resources.MkvWithAudio)
.AddParameter(String.Format("-f image2pipe -i pipe:.bmp -maxrate {0}k -r {1} -an -y {2}",bitrate, fps, outputfilename))
.Start();
There is documentation available here that shows how to get current percent of conversion.
I just found fflib at sourceforge. Looks pretty promising, haven't used it though.
How about writing a C++/CLI wrapper around ffmpeg's native interface and then calling your wrapper interface from your application?