I have a simple yet interesting question.
I need to start a process (a node.js server) from a C# application.
I found a piece of code explaining how to start the server from within the application.
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.FileName = #"c:\node\node.exe";**//Path to node installed folder****
string argument = "\\ bundle\main.js";
p.StartInfo.Arguments = #argument;
p.Start();
My question is : what happend with this process if the parent process (the C# application) crashes ? Will the child process exit/crash or will it keep running as it's a totally separate program ?
In the case it keeps running, is there a way to "link" those two processes to make sure the child exits if the parent crashes ?
Tried you code like as below , if you want close your process you have to use this function process.CloseMainWindow(); this will close process you started.
public static void Main()
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
startInfo.FileName = "cmd.exe";
process.StartInfo = startInfo;
process.Start();
Console.ReadLine();
process.CloseMainWindow();
process.Close();
}
In above code i started cmd.exe and as it has its own window i code CloseMainWindow() function to close that program.
as Cmd is separate process it will not get close when you close program which started it.
will this process keep running if the parent crashes (before the process.CloseMainWindow();) ?
answer to question is : Cmd process will not get closed if parent get closed before calling CloseMainWindow
try this for checking it
public static void Main()
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
startInfo.FileName = "cmd.exe";
process.StartInfo = startInfo;
process.Start();
throw new Exception("test");
Console.ReadLine();
process.CloseMainWindow();
process.Close();
}
in above code main program got exception and it get created before closing child process then in that case child process will run.
if you want to close External started process forcefully when application close , than make use of Application.ApplicationExit Event, and make call to CloseMainWindow() function of external process object.
Related
The second app is a console application and I want to see it's output window.
I know how to use Process.Start() but it doesn't show the console window for the app.
This is what I have tried:
Process.Start("MyApp.exe", "arg1 arg2");
So how to do it?
Perhapse this helps:
ProcessStartInfo info = new ProcessStartInfo(fileName, arg);
info.CreateNoWindow = false;
info.UseShellExecute = true;
Process processChild = Process.Start(info);
I figured it out. I have to run cmd command with /k argument (to keep the console window open) and then my whole command-line:
var command = "MyApp.exe arg1 arg2";
ProcessStartInfo processStartInfo = new ProcessStartInfo("cmd", "/k " + command);
processStartInfo.UseShellExecute = false;
Process process = new Process();
process.StartInfo = processStartInfo;
process.Start();
//In case you need the output. But you have to wait enough for the output
//string text = process.StandardOutput.ReadToEnd();
I want to start the Python Shell or IDLE as a child process of my WPF C# application using WindowsFormsHost.
For other applications it works just fine, but as the shell don't have a GUI so it gives problems.
I'm starting those other applications with this code:
Process p = new Process();
p.EnableRaisingEvents = true;
p.StartInfo.FileName = "/path/to/file.exe";
p.Start();
p.WaitForInputIdle();
while (p.MainWindowHandle == IntPtr.Zero) {
Thread.Sleep(100);
p.Refresh();
}
SetParent(p.MainWindowHandle, panel.Handle);
But p.WaitForInputHandle() gives some error about not having a graphical interface for the Python Shell.
So I thought that the IDLE is a graphical interface!
It isn't an executable, though. I found out that there are a .py and a .bat file to start it or through Python code.
I tried to start it through code:
if (!File.Exists(path)) {
string prg = #"import idlelib.idle
idlelib.idle.main()";
StreamWriter sw = new StreamWriter(path);
sw.Write(prg);
sw.Close();
}
Process p = new Process();
p.StartInfo.FileName = "python.exe";
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.Arguments = path;
p.Start();
I'm not sure if this is correct.
For now the python code is interpreted and the IDLE is started in the background of my application and as a standalone app.
I don't know how to set it as the son of the WindowsFormsHost.
I run PsExec in a WPF application, but after execution, the window closes.
Process process = new Process();
process.StartInfo.FileName = #"C:\Windows\SysWoW64\PsExec64.exe";
process.StartInfo.Arguments = String.Format(#"\\{0} ipconfig", TextBox_PCin.Text);
process.Start();
process.WaitForExit();
I also tried:
Process process = new Process();
process.StartInfo.FileName = #"C:\Windows\SysWoW64\PsExec64.exe";
process.StartInfo.Arguments = String.Format(#" \K \\{0} ipconfig", TextBox_PCin.Text);
process.Start();
process.WaitForExit();
but nothing happens here. A window appears only for a second.
How can I stop the window from closing? Why doesn't "WaitForExit" do it?
Try running:
Process process = new Process();
process.StartInfo.FileName = #"C:\Windows\System32\cmd.exe";
process.StartInfo.Arguments = String.Format(#"/k C:\Windows\SysWoW64\PsExec64.exe \\{0} ipconfig", TextBox_PCin.Text);
process.Start();
process.WaitForExit();
WaitForExit did not work for you because PsExec64.exe does not wait for user input at all. It take commands as an argument >> parse & run it >> exit process. So technically your "code" did wait for PsExec64.exe to exit and then continued.
I have been messing around with triggering a bash script via C#. This all works fine when I first call the "open" command with arguments which in turn opens my .command script via Terminal.
Once the "open" command is used once Terminal or iTerm will remain open in the background, at which point calling the "open" command with arguments then has no further effect. I sadly have to manually quit the application to trigger my script again.
How can I pass arguments to an already open terminal application to restart my script without quitting?
I've searched online ad can't seem to work it out, it already took a good amount of time solve the opening code. Your help is much appreciated.
Here is the C# code I'm using to start the process:
var p = new System.Diagnostics.Process();
p.StartInfo.FileName = "open";
p.StartInfo.WorkingDirectory = installFolder;
p.StartInfo.Arguments = "/bin/bash --args \"open \"SomePath/Commands/myscript.command\"\"";
p.Start();
Thanks
EDIT:
Both answers were correct, this might help others:
ProcessStartInfo startInfo = new ProcessStartInfo("/bin/bash");
startInfo.WorkingDirectory = installFolder;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.StandardInput.WriteLine("echo helloworld");
process.StandardInput.WriteLine("exit"); // if no exit then WaitForExit will lockup your program
process.StandardInput.Flush();
string line = process.StandardOutput.ReadLine();
while (line != null)
{
Debug.Log("line:" + line);
line = process.StandardOutput.ReadLine();
}
process.WaitForExit();
//process.Kill(); // already killed my console told me with an error
You can try:
before calling p.Start():
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
// for the process to take commands from you, not from the keyboard
and after:
if (p != null)
{
p.StandardInput.WriteLine("echo helloworld");
p.StandardInput.WriteLine("executable.exe arg1 arg2");
}
(taken from here)
This is what you may be looking for :
Gets a stream used to write the input of the application.
MSDN | Process.StandardInput Property
// This could do the trick
process.StandardInput.WriteLine("..");
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Redirect Standard Output Efficiently in .NET
Capturing console output from a .NET application (C#)
I know how to execute something like this:
SomeEXE inputfile.txt
in the command prompt via C#.
The problem I am having is that SomeEXE opens another command prompt where it writes the outputs given inputfile.txt.
Is it generally possible to obtain these outputs? Thanks.
Here is my current code:
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 SomeEXE inputfile.txt";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
process.StartInfo = startInfo;
process.Start();
// Now use streams to capture the output
StreamReader outputReader = process.StandardOutput;
process.WaitForExit();
String line = outputReader.ReadToEnd();
ProcessStartInfo processStartInfo = new processStartInfo("SomeEXE", "inputfile.txt");
processStartInfo.UseShellExecute = false;
processStartInfo.ErrorDialog = false;
// Here is where you grab the output:
processStartInfo.RedirectStandardOutput = true;
Process process = new Process {
StartInfo = processStartInfo
};
process.Start();
// Now use streams to capture the output
StreamReader outputReader = process.StandardOutput;
process.WaitForExit();
Now you can read the outputStream as necessary.
I am guessing this is what you mean. Also, here are the docs on RedirectStandardOutput
Also, if you know the path to the file that was generated (assuming the SomeEXE wrote to another file) you can use File.Open to access its contents after SomeEXE has executed (remember to wait until after otherwise SomeEXE may still have a handle on the file making it difficult to read it).