.net代码关机

这段代码主要使用的是P/Invoke技术,如果对这个技术还未有接触,请花一些时间学习一下。P/Invoke不是一个能在一篇帖子里能讲明白的东西。

PS.简言之,P/Invoke = Platform Invoke,就是在.NET程序中调用Windows API等非托管函数的技术。

 

Code Snippet

// 引入必要的命名空间

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;    // 提供DllImport等特性,是P/Invoke的关键

 

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

 

          // 这个结构体将会传递给API。使用StructLayout(...特性,确保其中的成员是按顺序排列的,C#编译器不会对其进行调整。

          [StructLayout(LayoutKind.Sequential, Pack = 1)]
          internal struct TokPriv1Luid
          {
              public int Count;
              public long Luid;
              public int Attr;
          }

 

          // 以下使用DllImport特性导入了所需的Windows API。

          // 导入的方法必须是static extern的,并且没有方法体。调用这些方法就相当于调用Windows API。

          [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);

 

          // 以下定义了在调用WinAPI时需要的常数。这些常数通常可以从Platform SDK的包含文件(头文件)中找到

  • EWX_FORCE-强行终止未响应关机命令的进程。

    注意: 使用此标志会导致数据丢失,因为 Windows 不会发送到计算机中当前正在运行的应用程序的 WM_QUERYENDSESSION 和 WM_ENDSESSION 的消息。只有在不重要数据丢失的情况下使用此标志。
  • EWX_LOGOFF-终止所有进程,然后注销计算机。
  • EWX_POWEROFF-关闭计算机,然后关闭电源关闭电源功能的系统中。在 Windows NT 和 Windows 2000 下,过程调用 ExitWindowsEx 函数,利用此标志,必须具有 SE_SHUTDOWN_NAME 特权。Windows 95 和 Windows 98 中,我不支持或要求这项特权的 Windows。
  • EWX_REBOOT [ASCII 150] 关闭,然后重新启动计算机。在 Windows NT 和 Windows 2000 下,过程调用 ExitWindowsEx 函数,利用此标志,必须具有 SE_SHUTDOWN_NAME 特权。Windows 95 和 Windows 98 中,我不支持或要求这项特权的 Windows。
  • EWX_SHUTDOWN-关闭计算机,则可以安全地关闭电源的点。缓冲区已被刷新到磁盘的所有文件和所有正在运行的进程已停止。在 Windows NT 和 Windows 2000,调用 ExitWindowsEx 函数与此标志在过程必须具有 SE_SHUTDOWN_NAME 特权。windows 95、 Windows 98 和我不支持或不需要此特权的 Windows。

          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;

 

          // 通过调用WinAPI实现关机,主要代码再最后一行ExitWindowsEx,这调用了同名的WinAPI,正好是关机用的。

          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);
          }

 

          private void button1_Click(object sender, EventArgs e)
          {
              if (radioButton1.Checked == true)
              {
                  DoExitWin(EWX_SHUTDOWN); 
              }
              else
              {
                  Application.Exit(); 
              }
              //MessageBox.Show("2");
          }
      }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
net use \\目标IP\ipc$ "密码" /user:"administrator" 条件: 一:超级用户。 二:超级用户要有密码。 三:远程机的"控制面板-文件夹选项-查看-简单的文件共享",需去掉选取。 IPC$连接windows xp提示1326错误的解决方法 1326错误解决方法:(输入无误的前提下) net use \\目标IP\ipc$ "密码" /user:"administrator"进行连接,报告系统发生1326错误,登陆失败:未知用户名或密码错误。在远程机的"控制面板-文件夹选项-查看-简单的文件共享",去掉选取,然后再尝试连接。简单文件共享会 把网络连接权限都归为 guest连接,是无法访问IPC$等管理共享的。 因为也是我花了蛮大的功夫才弄清楚原因的(答案也是在网上找到的,当时没有注意网址,现在又找不到了,感谢原创作者),而且看到网上很多人有同样的困扰,然而网上关于这个问题的解释都不能解决本质的问题,所以既然我知道了,也就不吝啬的与大家一起分享~ 发生错误 1219。 不允许一个用户使用一个用户以上用户名与一个服务器或共享资源的多重连接。中断与次服务器或共享资源的所有连接,然后在试一次... 建立ipc$空连接时,容易出现上述错误。 解决方法: net use \\机器名或IP\ipc$ /del 用net use来删除前一个用户的连接 net session这条命令看看你的共享文件夹的电脑上有几个连接 希望喜欢计算机的朋友们继续加油!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值