Windows 95 重新開機十分簡單,只要呼叫 ExitWindowsEx API 函數就可以了, 例如:
API 宣告式:
Private Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long
Private Enum HowExitConst
EWX_LOGOFF = 0 ' 登出
EWX_REBOOT = 2 ' 重開機
EWX_SHUTDOWN = 1 ' 關機
EWX_FORCE = 4 ' 強制關機
End Enum
呼叫敘述:
Call ExitWindowsEx(how, 0)
' how 等於 EWX_LOGOFF 、 EWX_REBOOT 、 EWX_SHUTDOWN 、 或EWX_FORCE
但是這個方法並不能對 NT 關機或重新開機,
原因是 NT 比較著重安全性(Security), 而為了讓 NT 關機或重新開機, 則必須在呼叫
ExitWindowsEx 之前, 呼叫 AdjustTokenPrivileges API,
而 呼叫 AdjustTokenPrivileges API 之前又有一堆設定值要設定, 唉! 一言難盡,
好吧, 就給您一條現成的魚, 請在呼叫 ExitWindowsEx 之前呼叫以下的 AdjustToken
副程式就對了。
AdjustToken 副程式的細節如下:
1. API 的宣告:
Enum HowExitConst
EWX_FORCE = 4 ' 強制關機
EWX_LOGOFF = 0 ' 登出
EWX_REBOOT = 2 ' 重開機
EWX_SHUTDOWN = 1 ' 關機
End Enum
Const TOKEN_ADJUST_PRIVILEGES = &H20
Const TOKEN_QUERY = &H8
Const SE_PRIVILEGE_ENABLED = &H2
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 Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function LookupPrivilegeValue Lib "advapi32.dll" Alias "LookupPrivilegeValueA" (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 OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
註:如果以上的宣告放在「一般模組」底下, 應將 Declare 之前的 Private 保留字去掉, 並且在 Const 之前加上 Public 保留字。
2. AdjustToken 副程式:
Private Sub AdjustToken()
Dim hdlProcessHandle As Long Dim hdlTokenHandle As Long Dim tmpLuid As LUID Dim tkp As TOKEN_PRIVILEGES Dim tkpNewButIgnored As TOKEN_PRIVILEGES Dim lBufferNeeded As Long hdlProcessHandle = GetCurrentProcess() OpenProcessToken hdlProcessHandle, (TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY), hdlTokenHandle ' Get the LUID for shutdown privilege. LookupPrivilegeValue "", "SeShutdownPrivilege", tmpLuid tkp.PrivilegeCount = 1 ' One privilege to set tkp.Privileges(0).pLuid = tmpLuid tkp.Privileges(0).Attributes = SE_PRIVILEGE_ENABLED ' Enable the shutdown privilege in the access token of this process. AdjustTokenPrivileges hdlTokenHandle, False, tkp, Len(tkpNewButIgnored), tkpNewButIgnored, lBufferNeeded
End Sub
3. 呼叫的範例:
AdjustToken Call ExitWindowsEx(how, 0)
' how 等於 EWX_LOGOFF 、 EWX_REBOOT 、 EWX_SHUTDOWN 、 或EWX_FORCE
即時在 Windows 95 底下呼叫了 AdjustToken 也沒關係,
因為 Windows 95 並不會理會安全性的設定。