[Source] 電腦關機、登出、重新開機,不用再調用 Shutdown.exe 了!
一般要關機就直接開始選單選關機就行了,有時候要定時關機可能就會用到 Shutdown.exe,可是 Shutdown.exe 用起來有幾個小問題,像是無法關閉 Windows Server,或者如果使用者要阻止關機只要一個 -a 指令就可以了,甚至到系統資料夾把檔案直接殺掉...
其實 M$ 自己就有提供一個 API 可以讓我們調用關機、登出、重啟的動作!
Windows 2000 之後必須先把程式提權才能成功調用 ExitWindowsEx
C++
VB6 因為要手動宣告所以比較麻煩點...
以上源碼皆已在 Win7 x86 測試完成。
其實 M$ 自己就有提供一個 API 可以讓我們調用關機、登出、重啟的動作!
Windows 2000 之後必須先把程式提權才能成功調用 ExitWindowsEx
C++
HANDLE hdl; OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hdl); PTOKEN_PRIVILEGES ptoken = (PTOKEN_PRIVILEGES) new BYTE[sizeof(DWORD) + sizeof(LUID_AND_ATTRIBUTES)]; ptoken-> PrivilegeCount = 1; LUID uid; LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &uid); ptoken-> Privileges[0].Luid = uid; ptoken-> Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hdl, FALSE, ptoken, 0, NULL, NULL); CloseHandle(hdl); delete [](BYTE *)ptoken; ExitWindowsEx(EWX_FORCE|EWX_SHUTDOWN,0);
VB6 因為要手動宣告所以比較麻煩點...
Option Explicit
Private Declare Function OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function LookupPrivilegeValueA Lib "advapi32.dll" (ByVal lpSystemName As String, ByVal lpName As String, lpLuid As LUID) As Long
Private Declare Function AdjustTokenPrivileges Lib "advapi32.dll" (ByVal TokenHandle As Long, ByVal DisableAllPrivileges As Long, NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Long, PreviousState As TOKEN_PRIVILEGES, ReturnLength As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long
Private Const TOKEN_ADJUST_PRIVILEGES = &H20
Private Const TOKEN_QUERY = &H8
Private Const SE_PRIVILEGE_ENABLED = &H2
Private Const ANYSIZE_ARRAY = 1
Private Type LUID
lowpart As Long
highpart As Long
End Type
Private Type LUID_AND_ATTRIBUTES
pLuid As LUID
Attributes As Long
End Type
Private Type TOKEN_PRIVILEGES
PrivilegeCount As Long
Privileges(ANYSIZE_ARRAY) As LUID_AND_ATTRIBUTES
End Type
Private Const EWX_FORCE = 4
Private Const EWX_SHUTDOWN = 1
Private Const EWX_REBOOT = 2
Private Const EWX_LOGOFF = 0
Private Sub Command1_Click()
Dim hdl As Long
Dim uid As LUID
Dim ptoken As TOKEN_PRIVILEGES
Dim PreviousState As TOKEN_PRIVILEGES
Dim ReturnLength As Long
OpenProcessToken GetCurrentProcess, (TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY), hdl
LookupPrivilegeValueA "", "SeShutdownPrivilege", uid
ptoken.PrivilegeCount = 1
ptoken.Privileges(0).pLuid = uid
ptoken.Privileges(0).Attributes = SE_PRIVILEGE_ENABLED
AdjustTokenPrivileges hdl, False, ptoken, Len(PreviousState), PreviousState, ReturnLength
CloseHandle hdl
ExitWindowsEx EWX_SHUTDOWN Or EWX_FORCE, 0
End Sub
以上源碼皆已在 Win7 x86 測試完成。
留言
張貼留言