Start a subordinate process - c#

I would like to start a process from my application with Process.Start() and I would like that in case of my app crash or the user close it then the child process is automatically killed.
Is it possible to obtain something like this?

You can use the AppDomain.ProcessExit event to catch when your process is about to exit and have it kill the other process. I am unsure as to how it works in reaction to an unhandled exception, so you may have to use AppDomain.UnhandledException and have it use FailFast to handle any normal exceptions. As part of that handler, you have it kill the other process too.

You could store PID of lauched child process somewhere, then kill process with that PID in application closing event. Though in case of unhandled crash the child process may retain in memory.

Related

How to allow a process to be shut down cleanly

I have a process that I would like to be able to cleanly shut down from an external process. That is, I would like to give it a chance to clean up it's resources (save it's data etc.) before it dies.
Process.CloseMainWindow appears to be the ordinary way to go, except the process in question doesn't have any windows and I don't want to immediately call Process.Kill because I want to give it chance to clean up first (and a kill process command can't be intercepted by the target process).
So what is the best way to allow my process to be shut cleanly from another process?
I have control over both processes. The process to be shut does have a message loop (Application.Run()) so I would think there would be some message I could post through there.
I have read the msdn article on terminating processes and this article about closing processes cleanly however both mention methods that seem quite sophisticated despite the simplicity of what I am trying to achieve. Given that I have control over both processes I am hoping there's something a bit simpler that can be implemented cleanly in C#. Is there one?
The process to close is not a service, so can't do service stop.
I'm not sure if a .NET message loop supports thread messages, or only window messages. If it supports thread messages, then the terminating app can use PostThreadMessage() to post a WM_QUIT message (or a custom message that the message loop can look for) to the main thread of the target process so it can stop its message loop and exit the app.
Otherwise, have the target app create a named kernel event object using EventWaitHandle and then wait on the event, either by calling EventWaitHandle.WaitOne() in a manual thread, or calling ThreadPool.RegisterWaitForSingleObject() to use a system-provided thread pool. When the event is signaled, you can notify the main thread to exit the app. The terminating app can then open the event object by name using EventWaitHandle.OpenExisting(), and then signal the event with EventWaitHandle.Set().

Process.Kill() and process events

Here is the situation:
I have to create a program that would input another processes output stream into textbox. That it self wouldn't cause too much problem. What does, however, is the fact that I have to run 5 instances of this console application and redirect output to 5 textboxes, as well as to be able to kill any of these processes at any time. As far as I have learned, the best way to do this is asynchronously. But the problem here is with killing processes, that are created on different thread. How do I kill it without having access to it since it doesn't exist in scope where I have to kill it. My best guess is to get its PID on Process.Start(), so I can kill it, so...
Is it possible to fire any event from process on Process.kill() command?
And if not - is there a way to kill a process in about the same time interval as Process.Kill() that does fire some sort of event?
Or maybe someone could suggest me some other approaches or best practice on how these problems are usually solved?
EDIT: The reason I am running all processes on different threads is that I use Thread.Sleep() on some of them if there is and input parameter that tell me that the process must be killed after x seconds.
Process.Kill() command for some reason, does, in fact, fire process exited event. Easiest way for me to know that the process was killed, was by making a volatile string that holds information about how it ended. (Change it to "killed" before process.kill etc...)
First of all you do not need Threads at all. Starting a process is async in itself, so Process.Start(...) does not block and you can create as many processes as you want.
Instead of using the static Process.Start method you should consider creating Process class instances and set the CanRaiseEvents property to true. Further there are a couple of events you can register (per instance) - those will only raise if CanRaiseEvents is set to true, but also after a process is/has exited (including Kill() calls).
When you call
Process.Start()
it returns a Process class instance, which you can use to retrieve information from it output and kill that process any time
Process p = Process.Start("process.exe");
//some operations with process, may be in another thread
p.Kill()

Exit code of a process terminated with Process.Kill() in C#

In have 2 processes, a parent process and a child process. The parent process controls the lifecycle of child process i.e. parent process launches the child process when it needs the child to do some work and also it kills the child when it is done with it. To kill the child process, parent process is using Process.Kill() and process.WaitForExit() APIs.
Questions: -
I am observing that the exit code of the child process is always -1. Who is setting this exit code?
How can I change this exit code?
Process.Kill
No. Unless you pinvoke TerminateProcess() yourself, uExitCode argument.
Have a look at Reflector, this kind of stuff is easy to find with it.
The process exit code is likely being set by Win32. You can't change it. If you want to change the exit code, don't use Process.Kill as your IPC mechanism. Set an event or use other IPC primitives instead.

Ways to kill a running program and how to trap them?

We have different ways to kill a running C# program.
ctrl + C;
task bar then right click its icon, then select 'close' on the popup;
task manager, select the its executable name and then click end process;
console window, use kill command;
maybe more.
What I am asking here is how handle them in my C# program to guarantee my C# program exit gracefully when possible. I know how to trap ctrl + C, but don't the others. can you help me? thanks,
The best guarantee you have at code being run at exit is the finally statement.
Note though that your program will have to run in the try block when you use this mechanism.
I believe that the only time the block inside the finally is not executed are at:
A StackOverflowException;
Corrupted state exceptions (from .NET 4);
Forceful termination through the task manager (an unmanaged process kill);
Crash of the entire system (removing the power cable e.g.).
See Keep Your Code Running with the Reliability Features of the .NET Framework for an in depth analysis.
Scenario 2 basically calls Application.Exit(), which should amount to a graceful shutdown of all threads associated with your process. It also fires events you can use to perform any additional cleanup.
3 and 4 can be "trapped" by attaching a handler to the Application.ThreadException event of a WinForms app. This event is fired when any exception is about to be thrown out of the program to be handled by the runtime (which will terminate your assembly's execution and clean the sandbox). However, at this point there's very little you should do other than write something to the Event log or clean up any statics, like an IoC container or repository, and even that's problematic because if one of those objects caused the exception, you could very easily throw another exception in trying to deal with the last one.
Basically, if your user is using "kill" or "End Process" to close your app, there's something VERY wrong and you should probably address the underlying reason why a user would be doing that, before trying to gracefully capture such termination behaviors.
Cannot trap. You cannot avoid killing of a program. But you can always subscribe to kill. Just imaging how you can trap when people pull the power plug...
.NET 2.0
Subscribe to the AppDomain.CurrentDomain.ProcessExit event
.NET 3.5
Application.Exit Event
Useful links
AppDomain.CurrentDomain.ProcessExit and cleanup
How to detect when application terminates?
How to detect when main thread terminates?

Process management in .NET

So i have a helper process written in C++ and I open it, feed it arguments, and it feeds my program back information through the standardoutput stream.
PS. I don't have the source for the helper process exe.
If my application were to be terminated from the task manager, or for some reason crash, how could I ensure that my helper exe is closed? Is this possible? Would I need an external file?
Use Job Objects to manage groups of processes. In this case you want to create a job object using CreateJobObject, use SetInformationJobObject to set the JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE flag, and assign the helper process to the job using AssignProcessToJobObject. Don't close the handle to the job object unless you want to kill the helper process. When your process terminates (through any means), the handle will be closed and your helper process will be killed.
You should create an inheritable duplicate of the parent process handle and pass its value to the helper process on the commandline. The helper process can then wait on that handle on a separate thread (or the main thread if you're clever). When the handle becomes signaled, it means that the launching process has terminated.
Edit
Since you can't change the helper process, your options are more limited. Your could try attaching a handler to the launching process's OnAppDomainUnloaded event, but I'm not sure this will work in all the cases you're concerned about. You could also create a third process to monitor the first. This process would work as I described above. If you wanted to get really fancy, you could inject a remote thread into the helper process to monitor the parent. This is very technical, so I recommend against it.
The easiest way would be to close it on normal application exit and when AppDomain.CurrentDomain.UnhandledException is invoked (i.e. your app is about to crash)

Categories