2012-03-27 143 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 
}