很简单,我创建了一个简单的关闭计时器,它使用C#Forms通过命令提示符和相关的计时器运行shutdown命令。我注意到Windows会在事件发生之前显示一条通知,表明计算机即将关闭(我认为它不会超过15分钟左右)。
我的问题是:有没有办法阻止弹出通知出现而不与注册表交互或在Windows 7/8/10中进行侵入式更改?
我无法找到与本机Windows(OS)元素交互的良好资源,例如操作系统为这些类型的事件发布的弹出窗口和通知。无论如何要抓住那个事件并修改它(比如不显示通知)会很棒。但是一个更永久的解决方案,例如通过注册表或其他东西禁用它也很好。但我对程序化解决方案更感兴趣。
注意:如果没有侵入性处理方式,那么我对任何事情都很开放。我也试图重新学习表格,所以练习是值得的。
编辑:代码在GitHub并且已经完成,但我想将此功能添加到其中。
答案 0 :(得分:0)
基于McNets在his comment中所说的话:
为什么不使用标准。 windows shutdown命令?添加立即关闭系统的计划任务
我决定利用Window的Task Scheduler。我决定使用Task Scheduler,但还有其他人做类似的事情。
尽管这种方法比仅仅打开一个命令提示符更复杂,但它可以完成我需要的一切,包括绕过我在问题中提到的关闭横幅。注意,我仍然可以让用户选择使用像我之前所做的横幅运行它,但我还没有实现该功能。虽然这很简单(特别是下面的基本代码)。只需将计时器添加到shutdown args而不是/ t 1,并将任务设置为立即运行。
这可能不是唯一的解决方案,但它是我能找到的侵入性最小的。谢谢各位的帮助。我很感激。
全局:
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!");
}