C# 关机 Windows7 和windows 8

.Net技术 码拜 9年前 (2015-05-10) 950次浏览 0个评论
 

刚开始学C#,想做一个button响应来关机。从网上看了各种代码,以下是一个:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.Diagnostics;

namespace shutdown
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Process p = new Process();//实例化一个独立进程
            p.StartInfo.FileName = “cmd.exe”;//进程打开的文件为Cmd
            p.StartInfo.UseShellExecute = false;//是否启动系统外壳选否
            p.StartInfo.RedirectStandardInput = true;//这是是否从StandardInput输入
            p.StartInfo.CreateNoWindow = true;//这里是启动程序是否显示窗体
            p.Start();//启动
            p.StandardInput.WriteLine(“shutdown -s -t 1”);//运行关机命令shutdown (-s)是关机 (-t)是延迟的时间 这里用秒计算 10就是10秒后关机
            p.StandardInput.WriteLine(“exit”);
        }
    }
}
但是点击button以后弹出了同一个窗口,然后大断电看到p.StandardInput.WriteLine(“shutdown -s -t 1”);执行完了就弹出了窗口,试着把p.StartInfo.CreateNoWindow 设为false后看到程序执行到p.StandardInput.WriteLine(“shutdown -s -t 1”);以后弹出CMD窗口显示五句:the handle is invalid
为啥呢?对于这个独立进程没弄明白。

10分
直接执行就可以了,不用设置这个参数
引用 1 楼 caozhy 的回复:

直接执行就可以了,不用设置这个参数

参数删掉了,可是弹出一个系统的提示,大概意思是你愿意让这个程序更改系统吗
确认以后,又弹出了我的这个对话框。。。。就是不关机。。。

引用 1 楼 caozhy 的回复:

直接执行就可以了,不用设置这个参数

p.StandardInput.WriteLine(“shutdown -s”);
CMD还是弹出八个the handle is invalid
然后关闭CMD再弹出对话框,在点击button,弹出CMD 如图,我都废了。。。C# 关机 Windows7 和windows 8

10分
  //MyValue是目标计算机

ConnectionOptions op = new ConnectionOptions();
            op.Username = “administrator”;//或者你的帐号(注意要有管理员的权限) 
            op.Password = “”; //你的密码 
            ManagementScope scope = new ManagementScope(“\\” + MyValue + “\root\cimv2”, op);
            try
            {
                scope.Connect();
                System.Management.ObjectQuery oq = new System.Management.ObjectQuery(“SELECT * FROM Win32_OperatingSystem”);
                ManagementObjectSearcher query1 = new ManagementObjectSearcher(scope, oq);
                //得到WMI控制  
                ManagementObjectCollection queryCollection1 = query1.Get();
                foreach (ManagementObject mobj in queryCollection1)
                {
                    string[] str = { “” };
                    mobj.InvokeMethod(“ShutDown”, str);
                }
            }
            catch
            {

            }

10分
            Process p = new Process();
            p.StartInfo.FileName = "shutdown.exe";
            p.StartInfo.Arguments = "-s -t 1";
            p.Start();
只有我一个人测试了一下么
测试结果就是直接关机了,其他工作还没有保存
只能说Windows 8 64bit下测试时没有问题
10分
引用 6 楼 liuhuibing12 的回复:

只有我一个人测试了一下么
测试结果就是直接关机了,其他工作还没有保存
只能说Windows 8 64bit下测试时没有问题

这个问题跟shutdown命令的参数有关,在命令行下输入shutdown /? 可以看到:

 /f         强制正在运行的应用程序关闭,不前台警告用户。
            当为 /t 参数指定大于 0 的值时,
            则默示 /f 参数。
 /t xxx     设置关闭前的超时为 xxx 秒。
            有效范围是 0-315360000 (10 年),默认值为 30。
            如果超时时间大于 0,则默示 /f
            参数。

因此,把/t 后面的参数改为0即可实现非强制关机(注:Win xp的关机参数仅支持“-”,而在Win7及以上版本中,可用“/”代替“-”。

刚才的是Win7的解释,Win xp则不会因为-t的参数大于0而默示-f
引用 6 楼 liuhuibing12 的回复:

只有我一个人测试了一下么
测试结果就是直接关机了,其他工作还没有保存
只能说Windows 8 64bit下测试时没有问题

不好说,我的机器:

C# 关机 Windows7 和windows 8

最后结果:
[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 static 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);
        }

        public static void Reboot()
        {
            DoExitWin(EWX_FORCE | EWX_REBOOT);
        }

        public static void PowerOff()
        {
            DoExitWin(EWX_FORCE | EWX_POWEROFF);
        }

        public static void LogoOff()
        {
            DoExitWin(EWX_FORCE | EWX_LOGOFF);
        }

这个好使,最近很忙,先结贴了,但是闲下来还是要看看为嘛我用那段就不能关机。

引用 11 楼 baojay1989 的回复:

最后结果:
[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 static 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);
        }

        public static void Reboot()
        {
            DoExitWin(EWX_FORCE | EWX_REBOOT);
        }

        public static void PowerOff()
        {
            DoExitWin(EWX_FORCE | EWX_POWEROFF);
        }

        public static void LogoOff()
        {
            DoExitWin(EWX_FORCE | EWX_LOGOFF);
        }

这个好使,最近很忙,先结贴了,但是闲下来还是要看看为嘛我用那段就不能关机。

用不用这么复杂,Win8和Win7一个样的,Win7和XP 也只是命令参数有点小的差异而已
通用的代码:

            Process p = new Process();
            p.StartInfo.FileName = "shutdown.exe";
            p.StartInfo.Arguments = "-s -t 0";
            p.Start();

只要把后面的参数改为0就不会强制关机,想强制关机就加个“-f”,第3行改为:

p.StartInfo.Arguments = "-s -f -t 0";

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明C# 关机 Windows7 和windows 8
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!