要在程序关闭和pc关机时运行的代码

问题描述:

我有一个作为系统托盘应用程序运行的无窗口应用程序。我正在苦苦挣扎,因为它在计算机关闭或应用程序关闭时不得不运行代码。要在程序关闭和pc关机时运行的代码

这是我迄今为止

class sysTrayIcon 
{ 
    public sysTrayIcon() 
    { 
     AppDomain.CurrentDomain.ProcessExit += new EventHandler(exitCode); 
     SystemEvents.SessionEnding += new SessionEndingEventHandler(exitCode); 
    } 

    public void exitCode(object sender, EventArgs e) 
    {    
     contactCman appClosing = new contactCman(); 
     bool didWeSuceed = appClosing.stampUserOut();    
     if (didWeSuceed == false) 
     { 
      MessageBox.Show("Stamp out function run returned fail!!");     
     } 
     else 
     { 
      MessageBox.Show("Stamp out function run returned success"); 
     } 
    } 
} 

class contactCman 
{ 
    public Dictionary<string, string> getUrlResponse(string toDo) 
    { 
     var url = mainSiteUrl + "/" + apiFileName + "?" + "userid=" + userid + "&pw=" + pw + "&toDo=" + toDo; 
     HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; 
     HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
     WebHeaderCollection header = response.Headers; 
     var encoding = ASCIIEncoding.ASCII; 
     string responseText; 
     using (var reader = new System.IO.StreamReader(response.GetResponseStream(), encoding)) 
     { 
      responseText = reader.ReadToEnd(); 
     } 
     // key1=value1;key2=value2;key3=value3; 
     var responseData = responseText.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries) 
     .Select(part => part.Split('=')) 
     .ToDictionary(split => split[0], split => split[1]); 
     return responseData; 
    }  

    public Dictionary<string, string> checkLastStamp() 
    { 
     string toDo = "getLastStamp"; 
     Dictionary<string, string> urlResponse = getUrlResponse(toDo); 
     return urlResponse; 
    } 

    public bool stampUserOut() 
    { 
     Dictionary<string, string> usersLastStamp = checkLastStamp(); 
     string valueOfKey; 
     if (usersLastStamp.TryGetValue("checkInOut", out valueOfKey) && (valueOfKey == "in")) 
     { 
      string toDo = "stampUserOut"; 
      Dictionary<string, string> urlResponse = getUrlResponse(toDo); 
      if (urlResponse.TryGetValue("Message", out valueOfKey) && (valueOfKey == "Success!")) 
      { 
       return true; 
      } 
      else 
      { 
       return false; 
      } 
     } 
     else 
     { 
      return false; 
     }    
    } 
} 

我的问题是,当通过Visual Studio中的调试器中运行如预期上述工程的代码(仅与节目紧密,虽然测试)。如果我在外面运行它,消息箱永远不会出现。

+0

嗨,'SystemEvents.SessionEnding'事件可能是你想要的。 Lookee [here](http://social.msdn.microsoft.com/Forums/vstudio/en-US/ffd0b29b-4f89-4e4e-bcb7-863532203e89/shutdown-hook-in-c?forum=csharpgeneral) – 2014-10-08 13:12:17

我认为听听ApplicationExit事件可能会更好。它会阻止应用程序,直到执行处理程序实际上退出:如果你没有窗户

static void Main() 
{ 
    Application.ApplicationExit += Application_ApplicationExit; 

    ... 
} 

static void Application_ApplicationExit(object sender, EventArgs e) 
{ 
    MessageBox.Show("Exit!"); 
} 
+0

This works相当好。它甚至可以防止窗户关闭! – 2014-10-08 14:21:27

  1. SessionEnding不火。请参阅http://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents.sessionending%28v=vs.110%29.aspx
  2. ProcessExit仅运行2秒。这是为时已晚,以显示一个消息框,或做任何互动: http://msdn.microsoft.com/en-us/library/system.appdomain.processexit%28v=vs.110%29.aspx

我认为你要么需要一个服务,以便它可以登录/注销后活下去,或者你需要,所以你必须创建一个窗口一个消息泵。