作者:eaglet
網上介紹最多的兩種方法分別是:
system.diagnostics.process.start("shutdown",@"/r");
和 [dllimport("user32.dll")]
static extern bool exitwindow***(exitwindows uflags, shutdownreason dwreason);
[stathread]
static void main(string args)
這兩種方法在通常情況下工作是沒有問題的,但在某些特殊情況下,比如桌面被其它使用者鎖定時就無法重啟計算機。本人在實際工作中遇到過當當前螢幕被遠端控制軟體鎖定後,我做的後台守護程序試圖重啟計算機,結果用上述兩種方法都無法成功。分析原因,應該是遠端控制軟體用另外的帳號鎖定了螢幕(通常應該是windows service 或者 network service),這時守護程序用當前帳號重啟計算機就因為沒有許可權而失敗。
要解決這個問題,我們必須要給程序賦予足夠的許可權才行,於是我在呼叫 exitwindow*** 前執行了如下**來賦予當前程序關閉計算機許可權
//give current process seshutdownprivilege
tokpriv1luid tp;
intptr hproc = getcurrentprocess();
intptr htok = intptr.zero;
if (!openprocesstoken(hproc, token_adjust_privileges | token_query, ref htok))
tp.count = 1;
tp.luid = 0;
tp.attr = se_privilege_enabled;
if (!lookupprivilegevalue(null, se_shutdown_name, ref tp.luid))
if (!adjusttokenprivileges(htok, false, ref tp, 0, intptr.zero, intptr.zero))
上面**為當前程序賦予了關閉計算機的許可權。這裡需要注意的是上述**要執行成功同樣需要足夠的許可權,通常當前程序需要以擁有至少是系統管理員許可權的賬戶執行。如果沒有足夠許可權,需要用程式模擬系統管理員許可權,模擬其它帳號許可權的問題不在本文討論範圍內。
加上如上**後,在其他使用者鎖定機器後,重啟計算機成功。
下面給出完整**
using system;
using system.collections.generic;
using system.text;
using system.runtime.interopservices;
using system.threading;
public class exitwindows
[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 exitwindow***(int ***, 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 ***)
tp.count = 1;
tp.luid = 0;
tp.attr = se_privilege_enabled;
if (!lookupprivilegevalue(null, se_shutdown_name, ref tp.luid))
if (!adjusttokenprivileges(htok, false, ref tp, 0, intptr.zero, intptr.zero))
//exit windows
if (!exitwindow***(***, 0))
}///
/// reboot computer
///
/// force reboot
public static void reboot(bool force)
else
}///
/// reboot computer force if hung
///
public static void reboot()
///
/// shut down computer
///
/// force shut down
public static void shutdown(bool force)
else
}///
/// shut down computer force if hung
///
public static void shutdown()
///
/// log off
///
/// force logoff
public static void logoff(bool force)
else
}///
/// logoff computer force if hung
///
public static void logoff()
}摘自 eaglet
C 重啟計算機的問題
網上介紹最多的兩種方法分別是 system.diagnostics.process.start shutdown r 和 dllimport user32.dll static extern bool exitwindow exitwindowsuflags,shutdownreason dwrea...
C 遠端重啟計算機
什麼也不說了,直接看 using system using system.collections.generic using system.componentmodel using system.data using system.drawing using system.text using sy...
C 讓計算機自動重啟
怎樣讓計算機重新啟動 關機登出 主要是利用win32裡面的函式呼叫.bool exitwindow uint uflags,dword dwreason 第乙個引數關閉型別 有以下幾種型別 1 ewx logoff 關閉所有的程序 2 ewx poweroff 關閉電源 3 ewx reboot 關...