2014-02-13 73 views
5

我寫了這個小程序來演示該問題的要點:如何使一個控制檯應用程序退出正常關閉時

using System; 
using System.IO; 
using System.Threading; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     using (var disp = new MyDisp()) 
     { 
      using (var ewhLocalExit = new EventWaitHandle(false, EventResetMode.ManualReset)) 
      { 
       Console.WriteLine("Enter Ctrl+C to terminate the app."); 
       Console.CancelKeyPress += (_, e) => 
       { 
        e.Cancel = true; 
        ewhLocalExit.Set(); 
       }; 
       ewhLocalExit.WaitOne(); 
      } 
     } 
     File.AppendAllText("Log.txt", "Terminated.\n"); 
    } 
} 


class MyDisp : IDisposable 
{ 
    public MyDisp() 
    { 
     File.AppendAllText("Log.txt", "Started.\n"); 
    } 

    public void Dispose() 
    { 
     File.AppendAllText("Log.txt", "Disposed.\n"); 
    } 
} 

當我運行它,然後按Ctrl + C,我看「開始。 Disposed.Terminated「。在Log.txt中
當我運行它並用鼠標關閉它時,我只看到「開始」。

如何優雅地退出,以便至少可以看到「已處理」。 ?

回答

2

可以使用的DllImport導入SetConsoleControlHandler並用它來註冊封閉事件的事件處理程序(及其他),這裏是一個示例代碼片段,顯示它的工作(它會在log.txt中寫關閉whem您單擊X關閉控制檯):

class Program 
{ 
    [DllImport("Kernel32")] 
    public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add); 

    // A delegate type to be used as the handler routine 
    // for SetConsoleCtrlHandler. 
    public delegate bool HandlerRoutine(CtrlTypes CtrlType); 

    // An enumerated type for the control messages 
    // sent to the handler routine. 
    public enum CtrlTypes 
    { 
     CTRL_C_EVENT = 0, 
     CTRL_BREAK_EVENT, 
     CTRL_CLOSE_EVENT, 
     CTRL_LOGOFF_EVENT = 5, 
     CTRL_SHUTDOWN_EVENT 
    } 

    private static bool ConsoleCtrlCheck(CtrlTypes ctrlType) 
    { 
     if (ctrlType == CtrlTypes.CTRL_CLOSE_EVENT) 
      File.AppendAllText(@"Log.txt", "closed"); 

     return true; 
    } 

    private static void Main(string[] args) 
    { 
     SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true); 
     Console.WriteLine("Close me"); 
     Console.ReadLine(); 
    } 
} 

Source

2

當您通過單擊X按鈕用鼠標關閉控制檯應用程序時,您正在請求將該進程終止。

Wi32 API有一個SetConsoleControlHandler,它允許你指定一個處理器來處理各種事情。如果使用CTRL_CLOSE_EVENT調用處理程序,那麼您知道有人正試圖殺死您的應用程序。

有如何使用這個API的例子here

相關問題