查看完整版本: 用C#编写自己的关机程序(详细代码+详细注释+程序)

替身 2008-4-8 23:06

用C#编写自己的关机程序(详细代码+详细注释+程序)

给电脑设定某个时间,自动关机,或者自动重新启动?
我想这应该是众多朋友经常用到的功能吧.
可惜我们的操作系统,仅仅给我们提供了一个shutdown -s -t 300这样的不方便使用的命令.
所以, 我用了一晚上的时间, 用VS2005编写了一个C#版本的自动关机程序,
拿来和大家交流交流!

实现的功能:
指定日期时间模式,流逝时间模式下,
实现:
注销 >>> 重启 >>> 强制注销 >>> 关机 >>> 强制关机
共5种模式.

代码:
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
    }
}

[[i] 本帖最后由 替身 于 2008-4-8 23:13 编辑 [/i]]

jsjhcccn 2008-7-6 17:50

:_012 :_012 学习中哦

piaoxue_snow 2008-9-6 08:38

学习学习

chen2324727 2008-9-11 20:26

.................................

chen2324727 2008-9-11 20:27

.................................

chen2324727 2008-9-11 20:28

...............................

pengge 2008-10-26 01:03

恩。有些意思哦!
我那天写的是用
exitwindows直接的关!
可以是可以,但是。不是很好、
没有结束当前的进程。会出现保存的提示。呵呵。先结束了当前的:_003

sanky 2008-10-26 11:46

有得学习了,努力学呀!

BlueBing 2008-11-11 21:51

学习下
很有借鉴价值

BlueBing 2008-11-11 21:52

有需要改进的地方。。

BlueBing 2008-11-12 19:47

下载的压缩文件都是损坏的。。
什么情况

syc747 2008-11-13 23:09

学习了,楼主辛苦了

liubing01223 2008-11-18 09:24

很不错

要好好学习 啊。一定要好好学习
页: [1]
查看完整版本: 用C#编写自己的关机程序(详细代码+详细注释+程序)