Capture console exit C#

前端 未结 10 1888
悲&欢浪女
悲&欢浪女 2020-11-22 04:01

I have a console application that contains quite a lot of threads. There are threads that monitor certain conditions and terminate the program if they are true. This termi

相关标签:
10条回答
  • 2020-11-22 04:57

    The link mentioned above by Charle B in comment to flq

    Deep down says:

    SetConsoleCtrlHandler won't work on windows7 if you link to user32

    Some where else in the thread it is suggested to crate a hidden window. So I create a winform and in onload I attached to console and execute original Main. And then SetConsoleCtrlHandle works fine (SetConsoleCtrlHandle is called as suggested by flq)

    public partial class App3DummyForm : Form
    {
        private readonly string[] _args;
    
        public App3DummyForm(string[] args)
        {
            _args = args;
            InitializeComponent();
        }
    
        private void App3DummyForm_Load(object sender, EventArgs e)
        {
            AllocConsole();
            App3.Program.OriginalMain(_args);
        }
    
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool AllocConsole();
    }
    
    0 讨论(0)
  • 2020-11-22 04:59

    It sounds like you have the threads directly terminating the application? Perhaps it would be better to have a thread signal the main thread to say that the application should be terminated.

    On receiving this signal, the main thread can cleanly shutdown the other threads and finally close itself down.

    0 讨论(0)
  • 2020-11-22 05:02

    There is for WinForms apps;

    Application.ApplicationExit += CleanupBeforeExit;
    

    For Console apps, try

    AppDomain.CurrentDomain.DomainUnload += CleanupBeforeExit;
    

    But I am not sure at what point that gets called or if it will work from within the current domain. I suspect not.

    0 讨论(0)
  • 2020-11-22 05:02

    For those interested in VB.net. (I searched the internet and couldn't find an equivalent for it) Here it is translated into vb.net.

        <DllImport("kernel32")> _
        Private Function SetConsoleCtrlHandler(ByVal HandlerRoutine As HandlerDelegate, ByVal Add As Boolean) As Boolean
        End Function
        Private _handler As HandlerDelegate
        Private Delegate Function HandlerDelegate(ByVal dwControlType As ControlEventType) As Boolean
        Private Function ControlHandler(ByVal controlEvent As ControlEventType) As Boolean
            Select Case controlEvent
                Case ControlEventType.CtrlCEvent, ControlEventType.CtrlCloseEvent
                    Console.WriteLine("Closing...")
                    Return True
                Case ControlEventType.CtrlLogoffEvent, ControlEventType.CtrlBreakEvent, ControlEventType.CtrlShutdownEvent
                    Console.WriteLine("Shutdown Detected")
                    Return False
            End Select
        End Function
        Sub Main()
            Try
                _handler = New HandlerDelegate(AddressOf ControlHandler)
                SetConsoleCtrlHandler(_handler, True)
         .....
    End Sub
    
    0 讨论(0)
提交回复
热议问题