VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)
首页 - 经验之谈 - 如何讓 Windows(95 及 NT) 重新開機?
发表评论(0)作者:不详, 平台:VB6.0+Win98, 阅读:12381, 日期:2000-12-23
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 並不會理會安全性的設定。