<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      eaglet

      本博專注于基于微軟技術的搜索相關技術
        博客園  :: 首頁  :: 新隨筆  :: 聯系 :: 訂閱 訂閱  :: 管理

      C# 重啟計算機的問題

      Posted on 2012-04-13 13:54  eaglet  閱讀(13105)  評論(11)    收藏  舉報

      C# 程序重啟計算機的方法很多,網上也有不少這方面的文章,不過很多網上提供的方法在某些情況下無法獲取重啟計算機的權限導致重啟失敗。本文對這些方法做一些簡單的討論。

      作者:eaglet

       

      網上介紹最多的兩種方法分別是:

      System.Diagnostics.Process.Start("shutdown",@"/r");

          [DllImport("user32.dll")]
              static extern bool ExitWindowsEx(ExitWindows uFlags, ShutdownReason dwReason);
      
              [STAThread]
              static void Main(string[] args)
              {
                  ExitWindowsEx(ExitWindows.LogOff, ShutdownReason.MajorOther & ShutdownReason.MinorOther);
                  //這個語句將實現計算機注銷操作   
               }

       

      這兩種方法在通常情況下工作是沒有問題的,但在某些特殊情況下,比如桌面被其它用戶鎖定時就無法重啟計算機。本人在實際工作中遇到過當當前屏幕被遠程控制軟件鎖定后,我做的后臺守護進程試圖重啟計算機,結果用上述兩種方法都無法成功。分析原因,應該是遠程控制軟件用另外的帳號鎖定了屏幕(通常應該是windows service 或者 network service),這時守護進程用當前帳號重啟計算機就因為沒有權限而失敗。

      要解決這個問題,我們必須要給進程賦予足夠的權限才行,于是我在調用 ExitWindowsEx 前運行了如下代碼來賦予當前進程關閉計算機權限

       

       
              //give current process SeShutdownPrivilege
              TokPriv1Luid tp;
       
              IntPtr hproc = GetCurrentProcess();
       
              IntPtr htok = IntPtr.Zero;
       
              if (!OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok))
              {
                  throw new Exception("Open Process Token fail");
              }
       
              tp.Count = 1;
       
              tp.Luid = 0;
       
              tp.Attr = SE_PRIVILEGE_ENABLED;
       
              if (!LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref tp.Luid))
              {
                  throw new Exception("Lookup Privilege Value fail");
              }
       
              if (!AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero))
              {
                  throw new Exception("Adjust Token Privileges fail");
              }

      上面代碼為當前進程賦予了關閉計算機的權限。這里需要注意的是上述代碼要執行成功同樣需要足夠的權限,通常當前進程需要以擁有至少是系統管理員權限的賬戶運行。如果沒有足夠權限,需要用程序模擬系統管理員權限,模擬其它帳號權限的問題不在本文討論范圍內。

      加上如上代碼后,在其他用戶鎖定機器后,重啟計算機成功。

      下面給出完整代碼

      using System;
      using System.Collections.Generic;
      using System.Text;
      using System.Runtime.InteropServices;
      using System.Threading;
       
      public class ExitWindows
      {
          #region win32 api
          [StructLayout(LayoutKind.Sequential, Pack = 1)]
       
          private struct TokPriv1Luid
          {
       
              public int Count;
       
              public long Luid;
       
              public int Attr;
       
          }
       
          [DllImport("kernel32.dll", ExactSpelling = true)]
          private static extern IntPtr GetCurrentProcess();
       
          [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
          private static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
       
          [DllImport("advapi32.dll", SetLastError = true)]
          private static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
       
          [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
          private static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
              ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
       
          [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
          private static extern bool ExitWindowsEx(int flg, int rea);
       
          #endregion
       
          private const int SE_PRIVILEGE_ENABLED = 0x00000002;
       
          private const int TOKEN_QUERY = 0x00000008;
       
          private const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
       
          private const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
       
          #region Exit Windows Flags
          private const int EWX_LOGOFF = 0x00000000;
       
          private const int EWX_SHUTDOWN = 0x00000001;
       
          private const int EWX_REBOOT = 0x00000002;
       
          private const int EWX_FORCE = 0x00000004;
       
          private const int EWX_POWEROFF = 0x00000008;
       
          private const int EWX_FORCEIFHUNG = 0x00000010;
       
          #endregion
          
          public static void DoExitWin(int flg)
          {
       
              //give current process SeShutdownPrivilege
              TokPriv1Luid tp;
       
              IntPtr hproc = GetCurrentProcess();
       
              IntPtr htok = IntPtr.Zero;
       
              if (!OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok))
              {
                  throw new Exception("Open Process Token fail");
              }
       
              tp.Count = 1;
       
              tp.Luid = 0;
       
              tp.Attr = SE_PRIVILEGE_ENABLED;
       
              if (!LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref tp.Luid))
              {
                  throw new Exception("Lookup Privilege Value fail");
              }
       
              if (!AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero))
              {
                  throw new Exception("Adjust Token Privileges fail");
              }
       
              //Exit windows
              if (!ExitWindowsEx(flg, 0))
              {
                  throw new Exception("Exit Windows fail");
              }
          }
       
          /// <summary>
          /// Reboot computer
          /// </summary>
          /// <param name="force">force reboot</param>
          public static void Reboot(bool force)
          {
              if (force)
              {
                  DoExitWin(EWX_REBOOT | EWX_FORCE);
              }
              else
              {
                  DoExitWin(EWX_REBOOT | EWX_FORCEIFHUNG);
              }
          }
       
          /// <summary>
          /// Reboot computer force if hung
          /// </summary>
          public static void Reboot()
          {
              Reboot(false);
          }
       
          /// <summary>
          /// Shut down computer
          /// </summary>
          /// <param name="force">force shut down</param>
          public static void Shutdown(bool force)
          {
              if (force)
              {
                  DoExitWin(EWX_SHUTDOWN | EWX_FORCE);
              }
              else
              {
                  DoExitWin(EWX_SHUTDOWN | EWX_FORCEIFHUNG);
              }
          }
       
          /// <summary>
          /// Shut down computer force if hung
          /// </summary>
          public static void Shutdown()
          {
              Shutdown(false);
          }
       
          /// <summary>
          /// Log off
          /// </summary>
          /// <param name="force">force logoff</param>
          public static void Logoff(bool force)
          {
              if (force)
              {
                  DoExitWin(EWX_LOGOFF | EWX_FORCE);
              }
              else
              {
                  DoExitWin(EWX_LOGOFF | EWX_FORCEIFHUNG);
              }
          }
       
          /// <summary>
          /// logoff computer force if hung
          /// </summary>
          public static void Logoff()
          {
              Logoff(false);
          }
      }
      主站蜘蛛池模板: 成人国产精品日本在线观看| 亚洲欧美日韩成人综合一区| 亚洲av首页在线| 日韩人妻一区中文字幕| 亚洲天堂男人影院| 亚洲偷自拍另类一区二区| 国产一区二区三区黄色片| 亚洲人成网站在线播放2019| 国产伦一区二区三区久久| 芳草地社区在线视频| 国产乱子伦视频在线播放| 色九九视频| 亚洲男女内射在线播放| 和平县| 99久久精品国产亚洲精品| 国产精品普通话国语对白露脸| 国产成人精品午夜福利在线观看| 高清无打码一区二区三区| 国产精品色三级在线观看| 高清性欧美暴力猛交| 99热门精品一区二区三区无码| 亚洲成av人片乱码色午夜| 麻豆一区二区三区精品视频| 色综合热无码热国产| 中文字幕日韩有码第一页| 乱中年女人伦av三区| 中文国产日韩欧美二视频| 成人亚洲国产精品一区不卡| 久久夜夜免费视频| 一区二区三区放荡人妻| 成人永久性免费在线视频| 国产成人无码午夜视频在线播放| 深夜在线观看免费av| 无码人妻斩一区二区三区| 久久天天躁夜夜躁狠狠85| 马关县| 国产精品久久777777| 久久香蕉国产线看观看怡红院妓院 | 四虎影视www在线播放| 国产高跟黑色丝袜在线| 亚洲 一区二区 在线|