|
给电脑设定某个时间,自动关机,或者自动重新启动?
我想这应该是众多朋友经常用到的功能吧.
可惜我们的操作系统,仅仅给我们提供了一个shutdown -s -t 300这样的不方便使用的命令.
所以, 我用了一晚上的时间, 用VS2005编写了一个C#版本的自动关机程序,
拿来和大家交流交流!
引用:
实现的功能:
指定日期时间模式,流逝时间模式下,
实现:
注销 >>> 重启 >>> 强制注销 >>> 关机 >>> 强制关机
共5种模式.
如下图:
剩余时间少于30秒时,醒目提示:
复制内容到剪贴板 代码:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
namespace YanMang自动关机
{
///
/// 用于执行操作的委托
///
public delegate void MyActionDelegate();
public partial class FrmMain : Form
{
public FrmMain()
{
InitializeComponent();
}
//提示用户30秒后执行操作
private FrmTellUser ftu;
//离操作剩余的秒数
private int seconds;
//将要执行的操作
private string action;
///
/// 窗体加载
///
///
///
private void FrmMain_Load(object sender, EventArgs e)
{
//MessageBox.Show(this.dtpChooseTime.Text + this.btnOk.Text);
//MessageBox.Show(this.dtpChooseTime.Value.ToString());
//设定日期控件的最小值
this.dtpChooseTime.MinDate = DateTime.Now;
}
///
/// 执行操作
///
///
///
private void btnOk_Click(object sender, EventArgs e)
{
//关机: ExitWindowsEx(1, 0);
if (this.btnOk.Text == "执行设定(&D)")
{
//更改按钮功能
this.btnOk.Text = "放弃操作(&C)";
//禁用控件
this.panType.Enabled = false;
this.panTime.Enabled = false;
//计算秒钟的差值
if (!this.setSeconds())
{
MessageBox.Show("请检查您设定的时间是否合法!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
this.CancelAction();//取消操作
return;
}
//操作方式
foreach (Control cl in this.panType.Controls)
{
if (cl is RadioButton)
{
RadioButton rbt = (RadioButton)cl;
if (rbt.Checked)
{
this.action = rbt.Text;
}
}
}
//开启计时器
this.tmrActionDo.Start();
}
else
{
//取消操作
this.CancelAction();
}
}
///
/// 计时器
///
///
///
private void tmrActionDo_Tick(object sender, EventArgs e)
{
//显示剩余多少时间
this.timeLeaving();
switch (this.seconds)
{
case 31:
//提示用户
this.ftu = new FrmTellUser(new MyActionDelegate(this.CancelAction));
this.ftu.Action = this.action;
this.ftu.Show();
break;
case 0:
//停止计时器
this.tmrActionDo.Stop();
//执行操作
this.Do();
break;
}
this.seconds--;
}
///
/// 取消操作
///
private void CancelAction()
{
//更改按钮功能
this.btnOk.Text = "执行设定(&D)";
//解除控件禁用
this.panTime.Enabled = true;
this.panType.Enabled = true;
//清空信息
this.labInfo.Text = string.Empty;
this.seconds = 0;
this.action = string.Empty;
//关闭提示窗口
if (this.ftu != null)
{
this.ftu.Close();
}
//停止计时器
this.tmrActionDo.Stop();
}
//退出程序
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
//隐藏/显示窗体
private void btnHide_Click(object sender, EventArgs e)
{
this.Visible = !this.Visible;
if (this.Visible)
{
//显示时,自动激活界面.
this.Activate();
}
}
//鼠标单击图标
private void ntfShutDown_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
this.Visible = !this.Visible;
}
}
//执行选定操作
private void Do()
{
switch (this.action)
{
case "安全关机":
this.DoExitWin(EWX_SHUTDOWN);
break;
case "强制关机":
this.DoExitWin(EWX_POWEROFF);
break;
case "重新启动":
this.DoExitWin(EWX_REBOOT);
break;
case "注销登陆":
this.DoExitWin(EWX_LOGOFF);
break;
case "强制注销":
this.DoExitWin(EWX_FORCE);
break;
}
}
///
/// 用于计算"预定时间"与现在的时间之间的秒数
///
///
private bool setSeconds()
{
try
{
if (this.radDateTime.Checked)
{
//现在的时间
DateTime t1 = DateTime.Now;
//设定的时间
DateTime t2 = this.dtpChooseTime.Value;
//时间间隔
TimeSpan ts = t2 - t1;
//算出总共的秒差值
this.seconds = (int)ts.TotalSeconds;
}
else
{
//倒计时
this.seconds = Convert.ToInt32(this.numHour.Value.ToString()) * 3600 + Convert.ToInt32(this.numMinutes.Value.ToString()) * 60;
}
if (this.seconds > 0)
{
//成功!
return true;
}
else
{
return false;
}
}
catch
{
//出现错误则返回假
return false;
}
}
///
/// 剩余多少时间(显示给用户看的)
///
private void timeLeaving()
{
int tempNum = this.seconds;
//天数
int daysL = (int)(((double)tempNum) / 86400);
//小时
tempNum = (tempNum % 86400);//取余
int hoursL = (int)(((double)tempNum)/3600);
//分钟
tempNum = (tempNum % 3600);
int minutesL = (int)(((double)tempNum) / 60);
//秒数
int secondsL = (tempNum%60);
//显示
this.labInfo.Text = "将于" + daysL.ToString() + "天" + hoursL + "时" + minutesL + "分" + secondsL
+ "秒之后 " + this.action;
this.ntfShutDown.Text = "自动关机: " + this.labInfo.Text;
}
//时间选择器更改时,自动选中单选按钮
private void dtpChooseTime_ValueChanged(object sender, EventArgs e)
{
this.radDateTime.Checked = true;
}
//倒计时,自动选中单选按钮
private void numHour_ValueChanged(object sender, EventArgs e)
{
this.radBySeconds.Checked = true;
}
#region 关机用到的API代码
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}
[DllImport("kernel32.dll", ExactSpelling = true)]
internal static extern IntPtr GetCurrentProcess();
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool ExitWindowsEx(int flg, int rea);
internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
internal const int TOKEN_QUERY = 0x00000008;
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
internal const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
internal const int EWX_LOGOFF = 0x00000000;//注销
internal const int EWX_SHUTDOWN = 0x00000001;//关机
internal const int EWX_REBOOT = 0x00000002;//重新启动
internal const int EWX_FORCE = 0x00000004;//强制注销
internal const int EWX_POWEROFF = 0x00000008;//强制关机
internal const int EWX_FORCEIFHUNG = 0x00000010;
private void DoExitWin(int flg)
{
bool ok;
TokPriv1Luid tp;
IntPtr hproc = GetCurrentProcess();
IntPtr htok = IntPtr.Zero;
ok = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_ENABLED;
ok = LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref tp.Luid);
ok = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
ok = ExitWindowsEx(flg, 0);
}
#endregion
}
} |
|