2012-03-27 26 views
8

私はコンソールを閉じたときにファイルをアップロードする必要のあるC#アプリケーションを作成しています(Xボタンを押すか、コンピュータがシャットダウンされている)。コンソールを閉じるコードを実行しますか?

どうすればいいですか?私は赤い閉じるボタンをヒットしない場合は、コンソールにexitコマンドを発行する際に

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

のみ実行されます。

コンソールがXボタンで閉じられているときと、コンピュータがシャットダウンしているとき(通常Windowsを介しているときの両方で、電源がxDに引き込まれていれば解決できないことがわかります)

+3

は申し訳ありませんと言うんが、これは可能なすべての場合に動作させることはできませんので、あなたのプロセスが殺されるシナリオがありますシャットダウンを押すと、システムによってシャットダウンが防止され、シャットダウンを防ぐことができます) – Carsten

+0

@CarstenKönig私はこのような状況があると私は理解していますが、少なくともシャットダウン処理の下では、ユーザーはアプリケーションを強制終了しません。 –

+0

可能な複製http://stackoverflow.com/questions/474679/capture-console-exit-c-sharp –

答えて

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

これは完全に機能します! –

0

は、このような何かが

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


// find that one you interested in 
Process mypro; 

はあなたのため

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

万一作業のようにそれのProcess.Exitedイベントをサブスクライブ(私は右のあなたが要求し理解することを仮定して)であってもよいです。

+0

私はそういうことは決してしないと思います!なぜなら、「cmd」と呼ばれる複数のプロセスがある場合はどうなのでしょうか。プロセスに登録したい場合は、e.hのコードにフィルタリングを追加してください。プロセスウィンドウの名前であり、プロセス自体ではありません。 –

+0

@MarioFraiß:確かに。実際には、* cmd *のプロセスが私の投稿でどのようにスキップされたかに関する物語。 'cmd.exe'が要求されたことを知るには、「強力な鍵」が必要です。 – Tigran

1

私はまた、あなたが、あなたは無効なファイルがアップロード/壊れていませんので、後でアップロードしたいものを保存する必要があります提案したいでしょう。次回アプリケーションを起動すると、アップロードが実行されます。この1は、少なくともシステムのログオフ/シャットダウンのために動作します(多分あなたはどこwin7の上でそれを見てきました

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 
} 
関連する問題