Gracefuly stop .net initiated Java Process - c#

Having the next .net code, I want to stop it correctly so that the jvm executes it's ShutdownHooks.
System.Diagnostics.Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.WorkingDirectory = #"C:\test\";
p.StartInfo.FileName = #"C:\Program Files\Java\jre6u16\bin\java.exe";
p.StartInfo.Arguments = "-jar TheExecutable.jar";
Trying to stop the process with p.Kill() will force the jvm to stop without sending the equivalent SIGTERM found in the unix kill comand. Or maeby I am doing something wrong because the java process does not get it's shutdown hooks executed.
Thanks !

If you have control over the Java code, you could detect a fairly normal situation like End-Of-File in stdin, or a so-called poison pill in stdin, and use that to decide (in Java) that now is the time to exit.
Then to kill the java process, do whatever is needed to its stdin.
Another option is to write a signal handler, - see sun.misc.SignalHandler, and register this with sum.misc.Signal
Other options seem rather hideous - like polling the parent process or looking at a file.

Related

Can you make it so a C# program executes a CMD command on the same instance? [duplicate]

I figure out how to launch a process. But my problem now is the console window (in this case 7z) pops up frontmost blocking my vision and removing my focus interrupting my sentence or w/e i am doing every few seconds. Its extremely annoying, how do i prevent that from happening. I thought CreateNoWindow solves that but it didnt.
NOTE: sometimes the console needs user input (replace file or not). So hiding it completely may be a problems a well.
This is my current code.
void doSomething(...)
{
myProcess.StartInfo.FileName = ...;
myProcess.StartInfo.Arguments = ...;
myProcess.StartInfo.CreateNoWindow = true;
myProcess.Start();
myProcess.WaitForExit();
}
If I recall correctly, this worked for me
Process process = new Process();
// Stop the process from opening a new window
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
// Setup executable and parameters
process.StartInfo.FileName = #"c:\test.exe"
process.StartInfo.Arguments = "--test";
// Go
process.Start();
I've been using this from within a C# console application to launch another process, and it stops the application from launching it in a separate window, instead keeping everything in the same window.
#galets
In your suggestion, the window is still created, only it begins minimized. This would work better for actually doing what acidzombie24 wanted:
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
Try this:
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
I'll have to double check, but I believe you also need to set UseShellExecute = false. This also lets you capture the standard output/error streams.

Strange standard output behavior when blocking thread

I have a C# application that creates a thread which talks to Node.js (node.exe) over standard input.
The code to create this is pretty standard:
ProcessStartInfo NodeStart = new ProcessStartInfo();
NodeStart.FileName = FileName; // node.exe
NodeStart.Arguments = Arguments;
NodeStart.CreateNoWindow = true;
NodeStart.RedirectStandardError = true;
NodeStart.RedirectStandardInput = true;
NodeStart.RedirectStandardOutput = true;
NodeStart.UseShellExecute = false;
process = new Process();
process.OutputDataReceived += ReceivedOutput;
process.StartInfo = NodeStart;
process.Start();
process.BeginOutputReadLine();
The code works completely OK as long as I do not block the thread that is running it by using Thread.WaitOne(). As soon as I call Thread.WaitOne() something goes wrong with the input/output of the process. Next time I unblock the thread and write to standard input, I get nothing back. I inspected the process object in the debugger prior to when the standard input gets written and nothing appears to be wrong (node.exe is running and accepts the standard input).
It may simply be the case that standard input/output breaks when the thread blocks, but is this true? I couldn't find the answer anywhere.

C# Process WaitForExit hangs when starting python

I use a Process class to start Python like below (in a thread):
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "python.exe";
info.Arguments = "test.py";
Process p = new Process();
p.StartInfo = info;
p.RedirectStandardOutput = true;
p.RedirectStandardError = true;
...
p.Start();
p.WaitForExit();
when Python ends with errors (the python process is no longer showing in Windows Task Manager), WaitForExit still hangs. However, if I use IronPython instead, it works fine. Can anyone tell me why?
Resolved. Redirects and ErrorDataReceived/OutputDataReceived event implements causes this problem, use Redirects and StreamReader instead.
Try changing python.exe to pythonw.exe

Alternative native api for Process.Start

Ok this is not duplicate of "Alternative to Process.Start()" because my question is something different here.
I need to run a process and wait till execution of process and get the output of console.
There is way to set RedirectStandardOutput and RedirectStandardError to true, however this does not function well on some machines, (where .NET SDK is not installed), only .NET runtime is installed, now it works on some machines and doesnt work on some machines so we dont know where is the problem.
I have following code,
ProcessStartInfo info = new ProcessStartInfo("myapp.exe", cmd);
info.CreateNoWindow = true;
info.UseShellExecute = false;
info.RedirectStandardError = true;
info.RedirectStandardOutput = true;
Process p = Process.Start(info);
p.WaitForExit();
Trace.WriteLine(p.StandardOutput.ReadToEnd());
Trace.WriteLine(p.StandardError.ReadToEnd());
On some machines, this will hang forever on p.WaitForExit(), and one some machine it works correctly, the behaviour is so random and there is no clue.
Now if I can get a real good workaround for this using pinvoke, I will be very happy.
myapp.exe is nothing but writing 10 hello world statements on screen.
Could it be that your child process really hangs for ever, eg. waiting on input or displaying an error dialog that is not visible?
The native API is CreateProcess, and it's corresponding pInvoke.
Using a separate work around by calling native code is not going to correct the problem. The Process API is just a thin wrapper around the native Process functions - using them directly is just going to make your code more confusing and cause other problems.
It sounds like the problem, in this case, is your "myapp.exe". For some reason, that application is not terminating on those machines. If you discover what is causing that, you will likely be able to make this work correctly using Process.Start.
Ok I got this answer from somewhere...
using System.Diagnostics;
using System.Threading;
ProcessStartInfo info = new ProcessStartInfo("myapp.exe", cmd);
info.CreateNoWindow = true;
info.UseShellExecute = false;
info.RedirectStandardError = true;
info.RedirectStandardOutput = true;
Process p = new Process();
p.StartInfo = info;
p.BeginOutputReadLine();
p.BeginErrorReadLine();
AutoResetEvent wait = new AutoResetEvent(false);
p.Exited += (s,e)=>{
wait.Set();
}
p.Start();
wait.WaitOne();

Getting a Process to terminate

I have a process object setup like the following:
Process p = new Process();
p.StartInfo.FileName = command;
p.StartInfo.UseShellExecute = true;
p.StartInfo.Arguments = String.Format(
commandArguments,
destinationLocation,
sourceLocation,
sourceDirName,
(string.IsNullOrEmpty(revisionNotes.Text)) ? "" : revisionNotes.Text);
(where undefined values are supplied externally to this code and are valid). The process in question launches and properly executes with p.Start(); but i need to catch it on termination. The console window flashes up briefly and goes away which would seem to indicate that the process is done, but none of the relevant events are fired (OutputDataRecieved, Exited, etc) and it's like the process never ends. (I'm trying to execute a lua script with some parameters if that's relevant). Can someone help me get this process to stop correctly?
WaitForExit
Have you set the EnableRaisingEvents property of the process to True? You won't catch the Exited event without it.

Categories