2012-03-27 142 views
8

我正在編寫一個C#應用程序,當控制檯關閉時(需要通過X按鈕或關閉計算機),需要上傳文件。控制檯關閉時運行代碼?

我該怎麼做?

AppDomain.CurrentDomain.ProcessExit += new EventHandler (OnExit); 

只有當我發出命令exit到控制檯,而不是當我打紅關閉按鈕運行。

只有當控制檯通過X按鈕關閉以及計算機關閉時(通常通過Windows,我知道如果電源被拉到xD),解決方案纔會運行。

+3

抱歉,不這樣說,但是有些情況下你的進程被殺死,所以你不能得到這個在一切可能的情況下工作(也許你已經看到了Win7上,其中的場景你打了關機,系統告訴你有些進程阻止關機,你可以選擇終止它們) – Carsten 2012-03-27 20:34:59

+0

@CarstenKönig我知道有這樣的情況,但我希望它至少在正常關機過程中工作,如果用戶不會強制關閉應用程序。 – 2012-03-27 20:37:45

+0

可能的重複http://stackoverflow.com/questions/474679/capture-console-exit-c-sharp – 2012-03-27 20:39:29

回答

10

你必須調用WIN32 API,要做到這一點,只要看看這個帖子在這裏 http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/707e9ae1-a53f-4918-8ac4-62a1eddb3c4a/

我複製相關的代碼爲你從那裏:

class Program 

{ 
    private static bool isclosing = false; 

    static void Main(string[] args) 
    { 
     SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true); 

     Console.WriteLine("CTRL+C,CTRL+BREAK or suppress the application to exit"); 

     while (!isclosing) ; 
    } 

    private static bool ConsoleCtrlCheck(CtrlTypes ctrlType) 
    { 
     // Put your own handler here 

     switch (ctrlType) 
     { 
      case CtrlTypes.CTRL_CLOSE_EVENT: 
       isclosing = true; 
       Console.WriteLine("Program being closed!"); 
       break; 
     } 

     return true; 
    } 

    #region unmanaged 
    // Declare the SetConsoleCtrlHandler function 
    // as external and receiving a delegate. 

    [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 
    } 

    #endregion 
} 

這不正是你需要什麼。

問候,

+0

這個完美的作品! – 2012-03-27 21:05:58

0

可能是這樣的(假設我正確理解您的要求)

//get all command windows in the system 
Process[] processes = Process.GetProcessesByName("cmd"); 


// find that one you interested in 
Process mypro; 

訂閱Process.Exited事件它像你

mypro.Exited += (s,e) => 
{ 
    //here upload the file 
} 

應該工作。

+0

我想,你永遠不應該這樣做!因爲如果有多個稱爲「cmd」的單個進程會怎麼樣。如果你想訂閱這個過程,請添加一些過濾到代碼e.h.過程窗口的名稱而不是過程本身。 – 2012-03-27 20:43:10

+0

@MarioFraiß:當然。事實上,在我的文章中跳過了* that * cmd過程所在位置的故事。您需要一種「強大的密鑰」才能找到請求的「cmd.exe」。 – Tigran 2012-03-27 20:51:06

1

我也會想建議你保存你要上傳上傳以後,這樣你就不能有破損/無效的文件內容。這樣下一次應用程序啓動時,可以執行上傳。這其中至少適用於系統註銷/停機:

SystemEvents.SessionEnding += (SystemEvents_SessionEnding); 

private static void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e) 
{ 
    //code to run on when user is about to logoff or shutdown 
}