UPDATED...
I want to call kdiff from Console application. So I'm building two files and want to compare they at the end of executing my program:
string diffCmd = string.Format("{0} {1}", Logging.FileNames[0], Logging.FileNames[1]);
// diffCmd = D:\vdenisenko\DbHelper\DbHelper\bin\Debug\Reports\16_Nov 06_30_46_DiscussionThreads_ORIGIN.txt D:\vdenisenko\DbHelper\DbHelper\bin\Debug\Reports\16_Nov 06_30_46_DiscussionThreads_ORIGIN.txt
System.Diagnostics.Process.Start(#"C:\Program Files (x86)\KDiff3\kdiff3.exe", diffCmd);
//specification is here http://kdiff3.sourceforge.net/doc/documentation.html
It runs kdiff3 tool, but something wrong with filenames or command... Could you please look on screenshot and say what is wrong?
You need to use Process.Start():
string kdiffPath = #"c:\Program Files\Kdiff3.exe"; // here is full path to kdiff utility
string fileName = #"d:\file1.txt";
string fileName2 = #"d:\file2.txt";
Process.Start(kdiffPath,String.Format("\"{0}\" \"{1}\"",fileName,fileName2));
Arguments as described in the docs: kdiff3 file1 file2
var args = String.Format("{0} {1}", fileName, fileName2);
Process.Start(kdiffPath, args);
string kdiffPath = #"c:\Program Files\Kdiff3.exe"; // here is full path to kdiff utility
string fileName = #"d:\file1.txt";
string fileName2 = #"d:\file2.txt";
ProcessStartInfo psi = new ProcessStartInfo(kdiffPath);
psi.RedirectStandardOutput = true;
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
psi.Arguments = fileName + " " + fileName2;
Process app = Process.Start(psi);
StreamReader reader = app.StandardOutput;
//get reponse from console app in your app
do
{
string line = reader.ReadLine();
}
while(!reader.EndOfStream);
app.WaitForExit();
This will run the program from your console app
Process p = new Process();
p.StartInfo.FileName = kdiffPath;
p.StartInfo.Arguments = "\"" + fileName + "\" \"" + fileName2 + "\"";
p.Start();
Unless you are trying to do something else, in which case you need to provide more details.
Related
I want to make a windows form app in which with the press of a button will execute the commands of a bat file, but i do not want to have the bat file stored.
You could potentially do one of 2 things.
Create the file in a temp space. execute the cmd using process.start. and delete after its execution. you should wait for the command to end.
or you could open cmd with stdin and write the commands to the cmd.
public static string Execute(string file, params string[] args)
{
string argpass = "";
foreach (string arg in args)
argpass += "\"" + arg + "\" ";
var info = new ProcessStartInfo();
info.FileName = file;
info.Arguments = argpass;
info.UseShellExecute = false;
info.RedirectStandardOutput = true;
var p = Process.Start(info);
p.WaitForExit();
return p.StandardOutput.ReadToEnd();
}
Some think like this using the command
File.WriteAllText("TempScript.bat","batch data");
string outp = Execute(cmd,"TempScript.bat");
File.Delete("TempScript.bat");
I need to print multiple PDF-files from the hard-drive. I have found this beautiful solution of how to send a file to the printer. The problem with this solution is that if you want to print multiple files you have to wait for each file for the process to finish.
in the command shell it is possible to use the same command with multiple filenames: print /D:printerName file1.pdf file2.pdf
and one call would print them all.
unfortunately simply just to put all the filenames into the ProcessStartInfo doesn't work
string filenames = #"file1.pdf file2.pdf file3.pdf"
ProcessStartInfo info = new ProcessStartInfo();
info.Verb = "print";
info.FileName = filenames;
neither does it to put the filenames as Arguments of the Process
info.Arguments = filename;
I always get the error: Cannot find the file!
How can I print a multitude of files with one process call?
Here is an example of how I use it now:
public void printWithPrinter(string filename, string printerName)
{
var procInfo = new ProcessStartInfo();
// the file name is a string of multiple filenames separated by space
procInfo.FileName = filename;
procInfo.Verb = "printto";
procInfo.WindowStyle = ProcessWindowStyle.Hidden;
procInfo.CreateNoWindow = true;
// select the printer
procInfo.Arguments = "\"" + printerName + "\"";
// doesn't work
//procInfo.Arguments = "\"" + printerName + "\"" + " " + filename;
Process p = new Process();
p.StartInfo = procInfo;
p.Start();
p.WaitForInputIdle();
//Thread.Sleep(3000;)
if (!p.CloseMainWindow()) p.Kill();
}
Following should work:
public void PrintFiles(string printerName, params string[] fileNames)
{
var files = String.Join(" ", fileNames);
var command = String.Format("/C print /D:{0} {1}", printerName, files);
var process = new Process();
var startInfo = new ProcessStartInfo
{
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "cmd.exe",
Arguments = command
};
process.StartInfo = startInfo;
process.Start();
}
//CALL
PrintFiles("YourPrinterName", "file1.pdf", "file2.pdf", "file3.pdf");
It's not necessarily a simple solution, but you could merge the pdfs first and then send then to acrobat.
For example, use PdfMerge
Example overload to your initial method:
public void printWithPrinter(string[] fileNames, string printerName)
{
var fileStreams = fileNames
.Select(fileName => (Stream)File.OpenRead(fileName)).ToList();
var bundleFileName = Path.GetTempPath();
try
{
try
{
var bundleBytes = new PdfMerge.PdfMerge().MergeFiles(fileStreams);
using (var bundleStream = File.OpenWrite(bundleFileName))
{
bundleStream.Write(bundleBytes, 0, bundleBytes.Length);
}
}
finally
{
fileStreams.ForEach(s => s.Dispose());
}
printWithPrinter(bundleFileName, printerName);
}
finally
{
if (File.Exists(bundleFileName))
File.Delete(bundleFileName);
}
}
I need to run batch file, which has path (can contains spaces) as argument.
Batch file is really simple:
echo off
echo %1 > echotest.txt
Csharp code I am using to run this batch file:
ProcessStartInfo info = new ProcessStartInfo();
info.UserName = KIM_USER;
info.Password = ConvertToSecureString(KIM_USER_PASSWORD);
info.FileName = theTask.Path;
info.Arguments = "\"" + TranslateParameter(theTask.Parameter) + "\"";
info.Domain = Environment.MachineName;
info.WorkingDirectory = Path.GetDirectoryName(theTask.Path);
info.UseShellExecute = false;
info.CreateNoWindow = true;
Process batProcess = Process.Start(info);
batProcess.WaitForExit();
Basically in parameter comes e.g {Test_Path} and this is in TranslateParameter converted to real path, e.g: D:\Test Path\ (contains spaces)
This does not work for me, it returns me exit code 1 everytime.
If i remove \" from info.Arguments, it works, but in output file is just D:\Test
Any suggestions?
Regards
Can you try this if that works:
ProcessStartInfo info = new ProcessStartInfo();
info.UserName = KIM_USER;
info.Password = ConvertToSecureString(KIM_USER_PASSWORD);
info.FileName = theTask.Path + " \"" + TranslateParameter(theTask.Parameter) + "\"";
//info.Arguments = "\"" + TranslateParameter(theTask.Parameter) + "\"";
info.Domain = Environment.MachineName;
info.WorkingDirectory = Path.GetDirectoryName(theTask.Path);
info.UseShellExecute = false;
info.CreateNoWindow = true;
Process batProcess = Process.Start(info);
batProcess.WaitForExit();
I've been messing around with C# and in one moment of the code, I need to dump the output of an external .exe into a .txt. I do it by starting cmd.exe and then loading the program, with its attributes plus the > opperator. But now, when I execute the program, the file isn't even created. Meanwhile, if I input the EXACT same code that is passed to cmd in the program:
"o:\steam\steamapps\common\counter-strike global offensive\bin\demoinfogo.exe" "O:\Steam\SteamApps\common\Counter-Strike Global Offensive\csgo\testfile.dem" -gameevents -nofootsteps -deathscsv -nowarmup > "o:\steam\steamapps\common\counter-strike global offensive\demodump.txt"
directly into the Command Prompt, it does get dumped. I've been looking around, and I found A LOT of info, but sadlly nothing has helped me enough so far, so I decided to ask myself.
I attach the chunks of code that I think are relevant to this.
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = true;
startInfo.FileName = "CMD.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
if (checkBox1.Checked)
{
arguments += " -gameevents";
if (checkBox2.Checked)
{
arguments += " -nofootsteps";
}
if (checkBox3.Checked)
{
arguments += " -extrainfo";
}
}
if (checkBox4.Checked)
{
arguments += " -deathscsv";
if (checkBox5.Checked)
{
arguments += " -nowarmup";
}
}
if (checkBox6.Checked)
{
arguments += " -stringtables";
}
if (checkBox7.Checked)
{
arguments += " -datatables";
}
if (checkBox8.Checked)
{
arguments += " -packetentites";
}
if (checkBox9.Checked)
{
arguments += " -netmessages";
}
if (dumpfilepath == string.Empty)
{
dumpfilepath = getCSGOInstallationPath() + #"\demodump.txt";
}
baseOptions = #"""" + demoinfogopath + #"""" + " " + #"""" + demofilepath + #"""" + arguments;
startInfo.Arguments = baseOptions + " > " + #"""" + dumpfilepath + #"""";
try
{
using (exeProcess = Process.Start(startInfo))
....a bunch of code...
The Process class that you're creating has this useful little property:
Process.StandardOutput
When a Process writes text to its standard stream, that text is normally displayed on the console. By redirecting the StandardOutput stream, you can manipulate or suppress the output of a process. For example, you can filter the text, format it differently, or write the output to both the console and a designated log file.
All you need to do is ensure you're redirecting the StandardOutput to this stream (using the RedirectStandardOutput property in the ProcessStartInfo) and then you can read the output from that stream. Here's the MSDN sample code, slightly abridged:
Process myProcess = new Process();
ProcessStartInfo myProcessStartInfo = new ProcessStartInfo(args[0], "spawn");
myProcessStartInfo.UseShellExecute = false; // important!
myProcessStartInfo.RedirectStandardOutput = true; // also important!
myProcess.StartInfo = myProcessStartInfo;
myProcess.Start();
// Here we're reading the process output's first line:
StreamReader myStreamReader = myProcess.StandardOutput;
string myString = myStreamReader.ReadLine();
Console.WriteLine(myString);
If you look at the help for CMD (access by typing CMD /?) you'll see the following options:
/C Carries out the command specified by string and then terminates
/K Carries out the command specified by string but remains
Without one of those switches, CMD won't interpret the string you provide it as a command to execute.
When I write a short program like the following, it successfully generates a file... but only if I use either the /C or /K options:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = true;
startInfo.FileName = "CMD.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
var command = #"echo test > c:\users\myusername\Desktop\test.txt";
var args = "/C " + command;
startInfo.Arguments = args;
using (var process = Process.Start(startInfo)) { }
//Hi you could try this to build your process like this.
public class Launcher
{
public Process CurrentProcess;
public string result = null;
public Process Start()
{
CurrentProcess = new Process
{
StartInfo =
{
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
WorkingDirectory = #"C:\",
FileName = Path.Combine(Environment.SystemDirectory, "cmd.exe")
}
};
CurrentProcess.Start();
return CurrentProcess;
}
//Start the process to get the output you want to add to your .txt file:
private void writeOuput()
{
Currentprocess = new process();
Start()
CurrentProcess.StandardInput.WriteLine("Your CMD");
CurrentProcess.StandardInput.Close();
result = CurrentProcess.StandardOutput.ReadLine();
CurrentProcess.StandardOutput.Close()
//Then to put the result in a .txt file:
System.IO.File.WriteAllText (#"C:\path.txt", result);
}
}
}
All I am trying to do is send a command that opens a model with the program.exe
Supposed to be super simple!
Ex:
"C:\Program Files (x86)\River Logic\Enterprise Optimizer 7.4 Developer\EO74.exe" "C:\PauloXLS\Constraint Sets_1.cor"
The line above works well if pasted on the command prompt window.
However, when trying to pass the same exact string on my code it gets stuck on C:\Program
string EXE = "\"" + #tbx_base_exe.Text.Trim() + "\"";
string Model = "\"" + #mdl_path.Trim()+ "\"";
string ExeModel = EXE + " " + Model;
MessageBox.Show(ExeModel);
ExecuteCommand(ExeModel);
ExeModel is showing te following line on Visual Studio:
"\"C:\\Program Files (x86)\\River Logic\\Enterprise Optimizer 7.4 Developer\\EO74.exe\" \"C:\\PauloXLS\\Constraint Sets_1.cor\""
To me looks like it is the string I need to send in to the following method:
public int ExecuteCommand(string Command)
{
int ExitCode;
ProcessStartInfo ProcessInfo;
Process Process;
ProcessInfo = new ProcessStartInfo("cmd.exe", "/K " + Command);
ProcessInfo.CreateNoWindow = true;
ProcessInfo.UseShellExecute = true;
Process = Process.Start(ProcessInfo);
Process.WaitForExit();
ExitCode = Process.ExitCode;
Process.Close();
return ExitCode;
}
Things I've tried:
Pass only one command at a time (works as expected), but not an option since the model file will open with another version of the software.
Tried to Trim
Tried with # with \"
Can anyone see any obvious mistake? Thanks.
It's pretty straightforward. You just create a command line object then write to it, then to execute it you read back from it using SR.ReadToEnd():
private string GETCMD()
{
string tempGETCMD = null;
Process CMDprocess = new Process();
System.Diagnostics.ProcessStartInfo StartInfo = new System.Diagnostics.ProcessStartInfo();
StartInfo.FileName = "cmd"; //starts cmd window
StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
StartInfo.CreateNoWindow = true;
StartInfo.RedirectStandardInput = true;
StartInfo.RedirectStandardOutput = true;
StartInfo.UseShellExecute = false; //required to redirect
CMDprocess.StartInfo = StartInfo;
CMDprocess.Start();
System.IO.StreamReader SR = CMDprocess.StandardOutput;
System.IO.StreamWriter SW = CMDprocess.StandardInput;
SW.WriteLine("#echo on");
SW.WriteLine("cd\\"); //the command you wish to run.....
SW.WriteLine("cd C:\\Program Files");
//insert your other commands here
SW.WriteLine("exit"); //exits command prompt window
tempGETCMD = SR.ReadToEnd(); //returns results of the command window
SW.Close();
SR.Close();
return tempGETCMD;
}
Why are you opening a command prompt (cmd.exe)? Just pass the name of the executable.