網上介紹最多的兩種方法分別是:
system.diagnostics.process.start(
"shutdown"
,@"/r");和
[dllimport(
"user32.dll"
)]static
extern
bool
exitwindow***(exitwindowsuflags, shutdownreason dwreason);
[stathread]
static
void
main(
string
args)
這兩種方法在通常情況下工作是沒有問題的,但在某些特殊情況下,比如桌面被其它使用者鎖定時就無法重啟計算機。本人在實際工作中遇到過當當前螢幕被遠端控制軟體鎖定後,我做的後台守護程序試圖重啟計算機,結果用上述兩種方法都無法成功。分析原因,應該是遠端控制軟體用另外的帳號鎖定了螢幕(通常應該是windows service 或者 networkservice),這時守護程序用當前帳號重啟計算機就因為沒有許可權而失敗。
要解決這個問題,我們必須要給程序賦予足夠的許可權才行,於是我在呼叫 exitwindow*** 前執行了如下**來賦予當前程序關閉計算機許可權
//give current processseshutdownprivilege
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 intptrgetcurrentprocess();
[dllimport("advapi32.dll",exactspelling = true, setlasterror = true)]
private static extern boolopenprocesstoken(intptr h, int acc, ref intptr phtok);
[dllimport("advapi32.dll",setlasterror = true)]
private static extern boollookupprivilegevalue(string host, string name, ref long pluid);
[dllimport("advapi32.dll",exactspelling = true, setlasterror = true)]
private static extern booladjusttokenprivileges(intptr htok, bool disall,
ref tokpriv1luid newst, intlen, intptr prev, intptr relen);
[dllimport("user32.dll",exactspelling = true, setlasterror = true)]
private static extern boolexitwindow***(int ***, int rea);
#endregion
private const intse_privilege_enabled = 0x00000002;
private const int token_query =0x00000008;
private const inttoken_adjust_privileges = 0x00000020;
private const stringse_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 intewx_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(boolforce)
else
}///
/// reboot computer force ifhung
///
public static void reboot()
///
/// shut down computer
///
/// force shut down
public static void shutdown(boolforce)
else
}///
/// shut down computer force ifhung
///
public static void shutdown()
///
/// log off
///
/// force logoff
public static void logoff(boolforce)
else
}///
/// logoff computer force ifhung
///
public static void logoff()
}
C 重啟計算機的問題
作者 eaglet 網上介紹最多的兩種方法分別是 system.diagnostics.process.start shutdown r 和 dllimport user32.dll static extern bool exitwindow exitwindows uflags,shutdownr...
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 關...