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.
Related
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().
I need to do a lot of work in UI thread. This work consumes a lot of CPU and memory resources. In current realization I use Dispatcher.BeginInvoke() method, but it makes my application frozen.
What if I will delegate this job to child process without GUI? Main process run child process. After that main application sends some commands to child process, child process do some job and returns result object to host process?
How to communicate between host and child processes? I know about .NET remoting (marshaling), but it obsolete method (or not?).
Thanks and sorry for my bad english.
I've made a child process management library where the parent process and the child process are monitored due a bidirectional WCF pipe. If either the child process terminates or the parent process terminates each other is notified.
There is also a debugger helper available which automatically attaches the VS debugger to the started child process
You have a extendable communication infrastructure between the processes. No need for WCF knowledge.
Project site:
http://www.crawler-lib.net/child-processes
NuGet Packages:
https://www.nuget.org/packages/ChildProcesses
https://www.nuget.org/packages/ChildProcesses.VisualStudioDebug/
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()
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.
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)