What is the best way to kill an application instance?
I am aware of these three methods:
Application.Exit()
Environment.Exit(0)
Process.GetCurrentProcess().Kill()
Can anyone tell me which is better or when using each of the above would be appropriate?
guidelines from c# faq:
System.Windows.Forms.Application.Exit() - Informs all message pumps that they must terminate, and then closes all application windows after the messages have been processed. This method stops all running message loops on all threads and closes all windows of the application. This method does not force the application to exit. The Exit method is typically called from within a message loop, and forces Run to return. To exit a message loop for the current thread only, call ExitThread. This is the call to use if you are running a WinForms application. As a general guideline, use this call if you have called System.Windows.Forms.Application.Run.
System.Environment.Exit(exitCode) - Terminates this process and gives the underlying operating system the specified exit code. This call requires that you have SecurityPermissionFlag.UnmanagedCode permissions. If you do not, a SecurityException error occurs. This is the call to use if you are running a console application.
Killing the process is likely not recommended.
If this is a Windows Forms application, use Application.Exit(). That will close the program nicely.
Just a quick answer, I would always use the "Exit" option when it will work. It is a much cleaner way to do it.
To "Kill" a process means exactly that, and therefore the program does not get to do any cleanup work it might want to do (like saving configuration, saving other files, etc...). Unless you know what the process is and that it does not have any "cleanup" to do, and even then, it's just cleaner to use "Exit."
There does not appear to be any difference between the two "Exit" options you mention, I would wager that the first is simply implicitly passing the zero value.
foreach (Process proc in Process.GetProcessesByName("WindowsFormsApplication1.vshost"))
{
proc.Kill();
}
Related
Following are the ways by which we can exit an application:
Environment.Exit(0)
Application.Exit()
Form.Close()
What is the difference between these three methods and when to use each one?
The proper method would be Application.Exit(). According to the Documentation, it terminates all message loops and closes all windows thus giving your forms the possibility to execute their cleanup code (in Form.OnClose etc).
Environment.Exit would just kill the process. If some form has e.g. unsaved changes it would not have any chances to ask the user if he wants to save them. Also resources (database connections etc.) could not be released properly, files might not be flushed etc.
Form.Close just does what it says: it closes a form. If you have other forms opened (perhaps not now but in some future version of your application), the application will not terminate.
Keep in mind that if you use multithreading, Application.Exit() will not terminate your threads (and thus the application will keep working in the background, even if the GUI is terminated). Therefore you must take measures to kill your threads, either in the main function (i.e. Program.Main()) or when in the OnClose event of your main form.
they are all fine.
but form.Close() won't close your application
it closes the form and after that
the main-method returns an int (exitcode).
if you want that your application exits with exitcodes use
Environmet.Exit(exitcode) or return the exitcode in the main-method
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().
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 have an unhandled exception handler. It shows a nice GUI and allows users to send an error report. Users can even leave their name and phone number and things, and our support department calls them back. Works well, looks good, makes customers less angry. In theory, anyway.
The problem is that my application uses background threads, and the threads don't seem to care if an exception was thrown on, say, the GUI thread (which makes sense), and just continue their work. That eventually results in a WER dialog poping up if the user lets my custom exception handler window stay open long enough, making it look like the error handler itself crashed.
I don't have access to the thread objects in the scope of the exception handler, so I can't suspend them. Making the thread objects globally accessible is not a solution either. My workaround for now is to use something like Globals.Crashed = true; in my exception handler, and to have my thread methods check that property at every loop iteration. Not perfect, but it minimizes the damage.
Does anyone know a less-hacky method? Is my approach wrong? Do I have to do it like WER does and launch an external program that suspends the main program and shows the error UI?
If you have an unhandled, unknown exception, you can assume that ANYTHING has happend and that your program might fail to do even the most simple thing. Consider e.g. the case that it has consumed all available memory - then you won't be able to send the error report either, because it probably requires memory to be allocated.
A good approach is to write a separate small application that just does the error reporting. That application can pick up the details to report from a file. That way your unknown exception handler would:
Dump the info to a file in the temp directory.
Start the error reporting app with the file name as an argument.
Terminate the failing process, before it does something stupid.
The temp file should be removed by the error reporting app.
You could track all your threads in a global Collection object, so that when your handler executes, it could simply iterate through the collection object and abort the threads there.
Take a look at the code in this question, Suspend Process in C#, you'll need to tweak it so as to not suspend your GUI thread and any that aren't background ones you've started, but it should do the trick.
The better option, however, is to try and launch your error report GUI as a separate process, passing any required information to it, and then kill the original process from your unhandled exception handler, rather than allowing anything to run in a potentially corrupt state.
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)