C 重啟計算機的問題

2021-12-30 00:45:04 字數 3922 閱讀 1771

作者: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 關...