I was running some exe with ProcessStartInfo
ProcessStartInfo startInfo = new ProcessStartInfo("my.exe");
startInfo.Arguments = "foo.txt bar.txt";
startInfo.WorkingDirectory = path;
Process process = Process.Start(startInfo);
process.WaitForExit();
It was working fine on my PC, but when I move the code to another PC, the same code keep hanging.
After some trying, I was able to fix it by setting UseShellExecute to false (and use absolute path for the exe filename).
ProcessStartInfo startInfo = new ProcessStartInfo(Path.Combine(Server.MapPath(#"~\mypath"),"my.exe"));
startInfo.Arguments = "foo.txt bar.txt";
startInfo.UseShellExecute = false;
Process process = Process.Start(startInfo);
process.WaitForExit();
The question is why? Why does using shell hang the process? What is the difference between using or not using shell to execute?
Thanks for the help!
Related
I need to copy a file from one directory to another and do something with that file. I need to copy it with cmd, rather than File.Copy(), because I need the copy to be done as a part of ProcessStartInfo.
You can use this code and change startInfo.Arguments, but /C should be!
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new
System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C copy example.txt backup.txt";
process.StartInfo = startInfo;
process.Start();
You can create a bat-file to copy one or multiple files (using *). Then execute the batch file.
string batFileName = #"C:\{filePath}\copy.bat";
System.IO.File.WriteAllText(batFileName, #"copy {fileName}.{extension} {destination-filePath}");
System.Diagnostics.Process.Start(batFileName);
I was able to formulate this answer using the DOS Copy syntax along with this Stack Overflow QA
Start cmd window and run commands inside
var startInfo = new ProcessStartInfo {
FileName = "cmd.exe",
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
var process = new Process {StartInfo = startInfo};
process.Start();
process.StandardInput.WriteLine(#"copy c:\Source\Original.ext D:\Dest\Copy.ext");
process.StandardInput.WriteLine("exit");
process.WaitForExit();
I am using below codes with c# for executing doss command in the comment line i executed notepad and in the comment line i tried to execute excel but nobody running if i comment any one from notepad or excel then it executes. I want to execute dos commands one by one weather previous command finish its process or not.
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C notepad";
startInfo.Arguments = "/C excel";
process.StartInfo = startInfo;
process.Start();
By setting the Arguments property twice you are replacing "/C notepad" with "/C excel". The process is launching cmd.exe and passing only "/C excel" to it as an argument.
I suspect that cmd.exe cannot find the Excel exe when it's passed as a "/C" argument. This would explain why you don't see anything executing. You may need to specify the complete path to Excel.
If you want to execute both Notepad and Excel, you will need to launch them one after another by first setting one argument then calling Start for each application.
Something like this:
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
process.StartInfo = startInfo;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C notepad";
process.Start();
startInfo.Arguments = "/C {Insert the full path to Excel exe}excel";
process.Start();
Alternatively, you can launch both applications launched from the process rather then as parameters to cmd.exe. Process itself is cmd.exe. This will allow the OS to have a better chance of finding the application using the Windows Path variables
Something like this:
System.Diagnostics.ProcessStartInfo startInfo = new ProcessStartInfo();
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo = startInfo;
startInfo.FileName = "notepad";
process.Start();
startInfo.FileName = "excel";
process.Start();
I want to open IE (it doesn't matter the web site it will open with), but I found out that using this code:
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents = false;
proc.StartInfo.FileName = "http://www.google.com";
proc.Start();
will start the browser as a current user, but with this code:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "C:\\Program Files\\Internet Explorer\\iexplore.exe";
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
it wouldn't, why is that? what is the reason?
Wrap the code in a try catch and take a look at the exception being raised, that should help find out why it is not working.
I am having trouble executing an external console application using Process.Start
Process p = new Process();
p.StartInfo.WorkingDirectory = "dump";
p.StartInfo.FileName = "test.exe";
p.StartInfo.Arguments = s;
p.Start();
When the argument that p generates executes, the external application crashes, although if I copy the exact same argument in a command line window it runs fine.
So my question instead how would I create a new instance of a command window and then add the command test.exe + s to run?
So effectively I am launching cmd and then adding my arguments on to it
If you want to run test.exe prm1 prm2 via cmd, use cmd.exe /c test.exe prm1 prm2. Though I don't really understand what this has to do with the crashes. Sounds like your problem is with test.exe - find out what's causing it to crash, and that will help you fix your C# code so that you don't need the cmd.
One of the places I would examine is the working directory. When you set it to "dump", are you sure the current directory is what you expect? Try using a full path first. It's possible that test.exe happens to be in the system path so it gets executed, but its working directory is not what it expects, and this causes it to crash.
try this:
ProcessStartInfo processToRunInfo = new ProcessStartInfo();
processToRunInfo.Arguments = "Arguments");
processToRunInfo.CreateNoWindow = true;
processToRunInfo.WorkingDirectory = "C:\\yourDir\\";
processToRunInfo.FileName = "test.exe";
//processToRunInfo.CreateNoWindow = true;
//processToRunInfo.WindowStyle = ProcessWindowStyle.Hidden;
Process process = new Process();
process.StartInfo = processToRunInfo;
process.Start();
Process p = new Process();
p.StartInfo.WorkingDirectory = "/full/path/to/dump";
p.StartInfo.FileName = "/full/path/to/test.exe";
p.StartInfo.Arguments = s; // will call 'text.exe s'
p.Start();
Take a look at MSDN.
You need to Create an instance of the StartInfo class and user Start() such as
ProcessStartInfo startInfo = new ProcessStartInfo("IExplore.exe");
startInfo.WindowStyle = ProcessWindowStyle.Minimized;
Process.Start(startInfo);
startInfo.Arguments = "www.example.com";
Process.Start(startInfo);
Try it!
Rewriting your code would look something like this:
ProcessStartInfo startInfo = new ProcessStartInfo("test.exe");
startInfo.WindowStyle = ProcessWindowStyle.Minimized;
startInfo.WorkingDirectory = "dump";
startInfo.Arguments = "s";
Process.Start(startInfo);
I need to start the command window with some arguments and run more commands inside.
For example, launch a test.cmd and run mkdir.
I can launch the test.cmd with processstartinfo , but i am not sure how to run further commands. Can I pass further arguments to the test.cmd process?
How do I go about this?
Unable to add comments to answer... SO writing here.
Andrea, This is what I was looking for. However the above code doesnt work for me.
I am launching a test.cmd which is new command environment (like razzle build environment) and I need to run further commands.
psi.FileName = #"c:\test.cmd";
psi.Arguments = #"arg0 arg1 arg2";
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.CreateNoWindow = true;
psi.UseShellExecute = false;
Process p = new Process();
p.StartInfo = psi;
p.Start();
p.StandardInput.WriteLine(#"dir>c:\results.txt");
p.StandardInput.WriteLine(#"dir>c:\results2.txt");
You can send further commands to cmd.exe using the process
standard input. You have to redirect it, in this way:
var startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
var process = new Process {StartInfo = startInfo};
process.Start();
process.StandardInput.WriteLine(#"dir>c:\results.txt");
process.StandardInput.WriteLine(#"dir>c:\results2.txt");
process.StandardInput.WriteLine("exit");
process.WaitForExit();
Remember to write "exit" as your last command, otherwise the cmd process doesn't terminate correctly...
The /c parameter to cmd.
ProcessStartInfo start = new ProcessStartInfo("cmd.exe", "/c pause");
Process.Start(start);
(pause is just an example of what you can run)
But for creating a directory you can do that and most other file operations from c# directly
System.IO.Directory.CreateDirectory(#"c:\foo\bar");
Start a cmd from c# is useful only if you have some big bat-file that you don't want to replicate in c#.
What are you trying to achieve? Do you actually need to open a command window, or do you need to simply make a directory, for example?
mkdir is a windows executable - you can start this program in the same way you start cmd - there's no need to start a command window process first.
You could also create a batch file containing all the commands you want to run, then simply start it using the Process and ProcessStartInfo classes you're already using.
How come this doesn't work?
var startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = false
};
var process = new Process { StartInfo = startInfo };
process.Start();
process.StandardInput.WriteLine(#" dir");
process.WaitForExit();