11

In my application, the user is first presented with the log in screen, and the form that shows up after you log in has a menu bar.

On that menu bar are two items: "log out" and "exit". If the user selects the log out option, I want it to return to the aforementioned log in screen. If the user instead decided to click "exit", I prompt the user if they are sure they want to exit.

Unfortunately, when the user decides to close the program by clicking the "X" button on the window, it closes only the current form. My intention would be for it to close the entire application.

Basically, how can I exit the current application by intercepting the form closing event?

Under the Logout item, the strip code is:

 private void logoutToolStripMenuItem_Click(object sender, EventArgs e)
 {
     Form_Login log = new Form_Login();
     this.Close();
     log.Show();
 }

Under the Exit item, the strip code is:

 private void exitToolStripMenuItem_Click(object sender, EventArgs e)
 {
     if (MessageBox.Show("Are you sure to exit the programme ?","Exit",MessageBoxButtons.OKCancel)== DialogResult.OK)
     {
         Application.Exit();
     }
 }

And when I click the exit button, it closes the current form and I want to close the whole application.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Muhammed Salah
  • 271
  • 3
  • 4
  • 9

5 Answers5

21

This should handle cases of clicking on [x] or ALT+F4

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
   if (e.CloseReason == CloseReason.UserClosing)
   {
      DialogResult result = MessageBox.Show("Do you really want to exit?", "Dialog Title", MessageBoxButtons.YesNo);
      if (result == DialogResult.Yes)
      {
          Environment.Exit(0);
      }
      else 
      {
         e.Cancel = true;
      }
   }
   else
   {
      e.Cancel = true;
   }
}   
Sayse
  • 42,633
  • 14
  • 77
  • 146
JBelter
  • 415
  • 2
  • 5
  • 13
  • okai if i click logout menu strip item it will give me the message box too – Muhammed Salah Jul 22 '13 at 19:52
  • Let me do a bit of research and I'll get back to you. I know there is a way to detect if they are closing using the [X] button or even ALT+F4 – JBelter Jul 22 '13 at 19:55
  • jBelter, the closest you can get is using the FormClosingEventArgs – Sayse Jul 22 '13 at 20:08
  • @Sayse I know this, and I updated my code example to reflect this. I've done this in VB.net before, and it took me a little bit to refactor and change the code to more of what OP is looking for. – JBelter Jul 22 '13 at 20:09
  • Edited my answer into yours as you suggested, I did not want any credit for something that was basically yours – Sayse Jul 23 '13 at 13:31
  • Oh, actually we needed the `Environment.Exit(0)`. OP mentioned that previously pressing [x] would only close the form, not the entire application. Hence why we would need `Environment.Exit(0)` – JBelter Jul 23 '13 at 13:53
  • No problem, still learned that I can naturally close in my own applications now :) – JBelter Jul 23 '13 at 14:00
4
private void mainForm_FormClosing(object sender, FormClosingEventArgs e)
{
    if (MessageBox.Show("This will close down the whole application. Confirm?", "Close Application", MessageBoxButtons.YesNo) == DialogResult.Yes)
    {
        MessageBox.Show("The application has been closed successfully.", "Application Closed!", MessageBoxButtons.OK);
        System.Windows.Forms.Application.Exit();
    }
    else
    {
        this.Activate();
    }  
}
Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • 2
    Please add more description and/or information about your answer and how it solves the asked problem so others can easily understand it without asking for clarification – koceeng Feb 18 '17 at 09:19
2

If I am not wrong:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
   // You may decide to prompt to user
   // else just kill
   Process.GetCurrentProcess().Kill();
} 
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
  • 1
    @tnw Ok can u pls explain how will you terminate an App which has more than 100 `Foreground Threads` running? – Sriram Sakthivel Jul 22 '13 at 20:11
  • [`Environment.Exit(0)`](http://msdn.microsoft.com/en-us/library/system.environment.exit.aspx) comes to mind. Where did you even get the idea that force closing the current process counts as graceful or even a good idea? I think you'd be hard pressed to find a valid use case for that. – tnw Jul 22 '13 at 20:13
  • Did you know Environment.Exit(0) crashes in some `OS`? – Sriram Sakthivel Jul 22 '13 at 20:16
  • Tell me, how do you know what OS the OP is using? – tnw Jul 22 '13 at 20:18
  • `Environment.Exit(0)` makes process crash in `x64 Win7` no problem with `XP` as far as i've seen. – Sriram Sakthivel Jul 22 '13 at 20:18
  • OP may be using only one `OS` but it doesn't mean that his APP will be used in only one `OS`. My solution will work in all `OS`. do downvote with a valid reason.! Is `Environment.Exit(0)` Graceful? – Sriram Sakthivel Jul 22 '13 at 20:20
  • `Environment.Exit(0)` is much more graceful than `Process.GetCurrentProcess().Kill()` due to killing a process being a forced close. And correct me if I am wrong, but by killing the process it does not trigger dispose events – JBelter Jul 22 '13 at 20:23
  • Yes, it is. Your method won't even allow `finally` blocks to execute in addition to [critical finalizer objects](http://msdn.microsoft.com/en-us/library/system.runtime.constrainedexecution.criticalfinalizerobject.aspx) which can very easily cause resource leakage (streams, to name one, wouldn't have `dispose` called by the garbage collector). Quite frankly, your solution sucks. – tnw Jul 22 '13 at 20:23
  • And the fact that you can't get `Environment.Exit` to work properly on a particular OS points to you doing something wrong with that OS, not an issue with `Environment.Exit`. From your very vague and very wrong understanding of how it works, I doubt you could prove to Microsoft that the bug lies within their code, but I'd love to see you try. – tnw Jul 22 '13 at 20:27
  • I hope `Environment.Exit(0)` also wont execute finally blocks. are you sure? – Sriram Sakthivel Jul 22 '13 at 20:34
  • Not specifically to Only one `OS` we faced many issues from many systems regarding that then started to use Kill() obviously which is ungraceful but it does a termination rather failing or allowing Other `ForeGround` threads continue to run! – Sriram Sakthivel Jul 22 '13 at 20:37
  • @tnw - Is **completely** correct in what he is saying, from the [documentation for `Kill`](http://msdn.microsoft.com/en-us/library/system.diagnostics.process.kill.aspx) - "Data edited by the process or resources allocated to the process can be lost if you call Kill. Kill causes an abnormal process termination and should be used only when necessary" – Sayse Jul 22 '13 at 20:57
  • @Sayse I agree but I hope `Environment.Exit(0)` also won't execute finally blocks http://msdn.microsoft.com/en-us/library/system.environment.exit.aspx. If am wrong pls correct me – Sriram Sakthivel Jul 22 '13 at 21:00
  • It doesn't. That doesn't mean your solution is any better. You should only use `Process.GetCurrentProcess().Kill()` unless *absolutely have to*, and better options very clearly exist in this scenario. You just took your very specific use case, applied it to this one and didn't even bother to offer any kind of clarification or justification for your solution. – tnw Jul 22 '13 at 21:04
  • Neither does Process.Kill() so whats your point? [See this](http://stackoverflow.com/a/3304313/1324033)(finally wont be called if process finishes abrubtly).. you can try it yourself if you want `try{Process.Kill();}finally{Process.Start("notepad.exe");}` – Sayse Jul 22 '13 at 21:07
  • @tnw You put up a point that `Your method won't even allow finally blocks to execute`. So you give a justification for this. How can I execute all my `finally` safely. I'll agree with you then. – Sriram Sakthivel Jul 22 '13 at 21:07
  • I know it won't execute. that's not the point. I've faced issues with `Environment.Exit(0)` that's why I suggested `Kill()` for guaranteed termination. your criticism is accepted. but how to Terminate a App with large number of `Foreground` threads? – Sriram Sakthivel Jul 22 '13 at 21:12
  • Yeah, no, you haven't presented a single point that would indicate `Process.GetCurrentProcess().Kill()` would be a better solution. You're clearly doing something wrong if you can't get `Environment.Exit` to work properly. – tnw Jul 22 '13 at 21:12
  • I've posted an answer that will allow your finally blocks to be used, simply call `this.Close()` or similar to close your form – Sayse Jul 22 '13 at 21:17
  • That will allow form to close. but that will never terminate other Foreground thread – Sriram Sakthivel Jul 22 '13 at 21:19
  • the forms/applications disposal should care of that – Sayse Jul 22 '13 at 21:20
  • can't get you. you mean in Dispose we need to manually abort threads? – Sriram Sakthivel Jul 22 '13 at 21:21
  • threads reside within a process so when the process is disposed, so are its entities – Sayse Jul 22 '13 at 21:22
  • How will a process be disposed when you call form.close()? if a `Foreground` thread is alive process will **continue to run** try it. – Sriram Sakthivel Jul 22 '13 at 21:26
  • I just did, process died for me - [Heres my test code](http://ideone.com/dbrjGr) (simple form with 1 label on it nothing else) – Sayse Jul 22 '13 at 21:33
  • Nope. you've mistaken. your process is not died it is **ALIVE** pls check `TaskManager.exe` to ensure your process is alive still. To be specific your application will `Never` terminate. – Sriram Sakthivel Jul 22 '13 at 21:39
  • Nope. Insert Console.WriteLine(DateTime.Now.ToString()); inside while(true), then enable Console(Change your OutputType to ConsoleApplication) for Ur application to see It is died or not. – Sriram Sakthivel Jul 22 '13 at 21:51
  • Fair enough you are right there, a simple `th.Abort()` solved that though, abort is still safer than kill – Sayse Jul 22 '13 at 21:59
  • No your assumption about `Abort()` is wrong you can't abort a thread which is executing `UnManaged` code runtime will wait until it returns to managed code. consider your code waiting on `sock.recv()` where no data will be received? your app waits endlessly! – Sriram Sakthivel Jul 22 '13 at 22:02
  • @Sayse take a look at http://stackoverflow.com/questions/1559255/whats-wrong-with-using-thread-abort/1560567#1560567 you'll know Abort is `Evil` – Sriram Sakthivel Jul 22 '13 at 22:07
  • 3
    let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/33937/discussion-between-sayse-and-sriram-sakthivel) – Sayse Jul 22 '13 at 22:38
  • @tnw Take a look at this thread [Environment.Exit Fails](http://stackoverflow.com/questions/18036863/why-does-environment-exit-not-terminate-the-program-anymore) Sorry for registering a comment in Old Thread. I just wanna share you this **It is true** Thank you.! – Sriram Sakthivel Aug 06 '13 at 13:35
2

Apply the below code where you want to make the code to exit the application.

System.Windows.Forms.Application.Exit()
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
-1

Try this:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    // You may decide to prompt to user else just kill.
    Process.GetCurrentProcess().Goose();
} 
Sam
  • 7,252
  • 16
  • 46
  • 65