2016-12-31 243 views
1

很简单,我用C#窗体创建了一个简单的关闭计时器,它通过命令提示符和关联的计时器运行关闭命令。我注意到Windows显示一个通知,表明计算机将在事件发生之前即将关闭(我认为不到15分钟左右)。无关闭窗口的关闭窗口

我的问题是这样的:有没有办法阻止弹出通知出现,而不与注册表进行交互或在Windows 7/8/10中进行侵入式更改?

我一直没有找到一个很好的资源来与本机Windows(OS)元素进行交互,例如弹出窗口和操作系统为这些事件发布的通知。无论如何,捕捉该事件并修改它(如不显示通知)会很好。但一个更永久的解决方案,如通过注册表或其他东西禁用它也很好。但是我对程序化解决方案更感兴趣。

Windows 10 Shutdown Notification

注:如果有处理这种无侵入性的方式,那么我真的很开放的任何东西。我也在尝试重新学习表单,因此这个练习是值得的。

编辑:代码是在GitHub和几乎完成,但我想添加此功能。

+1

为什么不使用std。 windows'shutdown'命令?添加一个立即关闭系统的计划任务。 – McNets

+0

目前我使用shutdown -s -t [time]。如果您建议我使用超时功能,那么问题是如果用户关闭程序,我无法准确检查是否有关闭命令正在运行。但如果你建议我添加一个计划任务(在任务计划程序中),那么这是可能的,但我想要真的避免出于其他原因。但如果这是唯一的解决方案,那么就这样吧。我会快速拍摄! –

+1

只是八卦。你为什么试图关闭电脑而不提醒用户? – McNets

回答

0

基于什么McNets在his comment说:

为什么不使用std。 Windows关机命令?添加一个计划任务,立即关闭系统

我决定利用窗口的任务计划程序。我决定使用Task Scheduler,但也有其他人做类似的事情。

尽管这种方法比打开命令提示符更复杂一些,但它完成了我所需要的一切,包括规避了我在问题中提到的关闭横幅。请注意,我仍然可以让用户选择像我以前那样使用横幅来运行它,但我尚未实现该功能。这是相当微不足道的(特别是下面的基本代码)。只需将计时器添加到关闭参数而不是/ t 1,并将任务设置为立即运行。

这可能不是唯一的解决方案,但它是我能找到的侵入性最小的方法。谢谢各位的帮助。我很感激。

Full Source on GitHub

全局:

public const string DEFAULT_TASK_NAME = "ScheduledShutdownTimer"; 
private const string SHUTDOWN_COMMAND_ARGS = "/s /c \"Scheduled Computer shutdown via " + 
    "the Windows Shutdown Timer App\" /t 1"; 

创建任务:

using (TaskService ts = new TaskService()) 
{ 
    // If the task doesn't exist, create it. 
    if (TimerExists(DEFAULT_TASK_NAME)) 
     throw new TimerExists("The timer already exists in the task scheduler. You " + 
     "must modify it instead of attempting to create it!"); 
    else 
    { 
     try 
     { 
      TaskDefinition td = ts.NewTask(); 
      td.RegistrationInfo.Date = _currentTime; // DateTime.Now 
      td.RegistrationInfo.Source = "Windows Shutdown Timer"; 
      td.RegistrationInfo.Description = "Shutdown Timer initiated Windows " + 
       "Shutdown Timer"; 

      td.Settings.Enabled = true; 

      td.Triggers.Add(new TimeTrigger(_shutdownTime)); 
      td.Actions.Add(new ExecAction("shutdown", SHUTDOWN_COMMAND_ARGS, null)); 

      TaskService.Instance.RootFolder 
         .RegisterTaskDefinition(DEFAULT_TASK_NAME,td); 

      Properties.Settings.Default.ShutdownTimer = _shutdownTime; 
      Properties.Settings.Default.Save(); 

      StartLocalTimer(); 
     } 
     catch(Exception) 
     { 
      DialogResult alert = MessageBox.Show("The timer couldn't be set. ", 
       "Error - Couldn't Set Timer!", MessageBoxButtons.RetryCancel, 
       MessageBoxIcon.Error); 

      if (alert == DialogResult.Retry) 
       CreateShutdownTimer(numSeconds); 
     } 
    } 
} 

修改一个任务:

using (TaskService ts = new TaskService()) 
{ 
    // If the task exists, update the trigger. 
    if (TimerExists(DEFAULT_TASK_NAME)) 
    { 
     Task task = ts.GetTask(DEFAULT_TASK_NAME); 

     if (task.Definition.Triggers.Count == 1) 
      task.Definition.Triggers.RemoveAt(0); 

     else if (task.Definition.Triggers.Count > 1) 
     { 
      for (int index = 0; index < task.Definition.Triggers.Count - 1; index++) 
      { 
       task.Definition.Triggers.RemoveAt(index); 
      } 
     } 

     // Add the new trigger after making sure it is the only one. 
     task.Definition.Triggers.Add(new TimeTrigger(_shutdownTime)); 

     if (task.Definition.Actions.Count == 1) 
      task.Definition.Actions.RemoveAt(0); 

     else if (task.Definition.Actions.Count > 1) 
     { 
      for (int index = 0; index < task.Definition.Actions.Count - 1; index++) 
      { 
       task.Definition.Actions.RemoveAt(index); 
      } 
     } 

     // Add the new action after making sure it is the only one. 
     task.Definition.Actions.Add(new ExecAction("shutdown", SHUTDOWN_COMMAND_ARGS, 
     null)); 

     // Reset the status in case it was set as anything but "Ready" 
     task.Definition.Settings.Enabled = true; 
     task.RegisterChanges(); 

     Properties.Settings.Default.ShutdownTimer = _shutdownTime; 
     Properties.Settings.Default.Save(); 

     // Starts the timer display and enables/disables buttons. 
     StartLocalTimer(); 
    } 

    else 
     throw new NoTimerExists("The timer doesn't exist in the task scheduler. You " + 
     "must create it instead of attempting to modify it!"); 
} 

停止任务:

using (TaskService ts = new TaskService()) 
{ 
    // If the task exists, remove the trigger. 
    // Note: the included Stop() method doesn't work. 
    if (TimerExists(DEFAULT_TASK_NAME)) 
    { 
     Task task = ts.GetTask(DEFAULT_TASK_NAME); 
     task.Definition.Triggers.RemoveAt(0); 
     task.RegisterChanges(); 
     StopLocalTimer(); // Resets display timers in program 
    } 

    else 
     throw new NoTimerExists("The timer doesn't exist in the task scheduler. " + 
      "You must create it instead of attempting to modify it!"); 
}