| FAQ по Visual Basic |
| Содержание / Windows API |
|
|
§ 5.15. Как можно выключить или перезагрузить компьютер?
Для выполнения этих операций существует функция ExitWindowsEx:
Declare Function ExitWindowsEx Lib "user32" _
(ByVal uFlags As Long, _
ByVal dwReason As Long) As Long
Первый параметр задает тип выполняемого действия. Эти действия перечислены ниже: ' завершение сеанса пользователя Public Const EWX_LOGOFF = &H0& ' шатдаун компьютера Public Const EWX_SHUTDOWN = &H1& ' перезагрузка компьютера Public Const EWX_REBOOT = &H2& ' выключение компьютера (ATX) Public Const EWX_POWEROFF = &H8& ' флаг принудительного выполнения операции Public Const EWX_FORCE = &H4& ' флаг принудительного выполнения при зависании Public Const EWX_FORCEIFHUNG = &H10& Первые 4 константы задают конкретное действие. Остальные параметры — битовые модификаторы и их можно комбинировать. Флажок EWX_FORCE заставляет выполнить действие, не обращая внимания на протесты приложений (скажем, если в Word находятся несохраненные данные, то без флага EWX_FORCE действие не будет выполнено, пока пользователь не ответит на запрос Word'а). Флаг EWX_FORCEIFHUNG позволяет проигнорировать зависшие приложения. Второй параметр во всех системах до Windows XP являлся зарезервированным, а теперь ему нашли применение для указания причины, по которой нужно завершить сеанс работы системы. Небольшой пример. Перезагрузим компьютер с флагом EWX_FORCE:
ExitWindowsEx EWX_REBOOT Or EWX_FORCE, 0
Теперь перехожу к одному довольно интересному вопросу. Дело в том, что спокойно вызывать эту функцию можно только под Windows 9x; для NT же требуется сначала получить привилегию на это.
Private Declare Function GetCurrentProcess _
Lib "kernel32" () As Long
Private Declare Function OpenProcessToken _
Lib "advapi32.dll" _
(ByVal ProcessHandle As Long, _
ByVal DesiredAccess As Long, _
TokenHandle As Long) 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 Any, _
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 dwReason As Long) As Long
Private Declare Function GetVersionEx Lib "kernel32" _
Alias "GetVersionExA" _
(lpVersionInformation As OSVERSIONINFO) As Long
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(0) As LUID_AND_ATTRIBUTES
End Type
Private Type OSVERSIONINFO
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128
End Type
Const TOKEN_QUERY = &H8
Const TOKEN_ADJUST_PRIVILEGES = &H20
Const SE_SHUTDOWN_NAME = "SeShutdownPrivilege"
Const SE_PRIVILEGE_ENABLED = &H2
Const VER_PLATFORM_WIN32_NT = 2
Enum enmShutdownMode
smLogoff = 0
smShutdown = 1
smReboot = 2
smPoweroff = 8
smForce = 4
smForceIfHung = 16
End Enum
Public Function Shutdown( _
ByVal Mode As enmShutdownMode, _
Optional ByVal Reason As Long = 0 _
) As Boolean
Dim hToken As Long
Dim tp As TOKEN_PRIVILEGES
Dim osvi As OSVERSIONINFO
osvi.dwOSVersionInfoSize = Len(osvi)
GetVersionEx osvi
If osvi.dwPlatformId = VER_PLATFORM_WIN32_NT Then
If OpenProcessToken(GetCurrentProcess(), _
TOKEN_ADJUST_PRIVILEGES Or _
TOKEN_QUERY, hToken) _
Then
LookupPrivilegeValue vbNullString, _
SE_SHUTDOWN_NAME, tp.Privileges(0).pLuid
tp.PrivilegeCount = 1
tp.Privileges(0).Attributes = _
SE_PRIVILEGE_ENABLED
AdjustTokenPrivileges hToken, False, tp, _
0, ByVal 0&, 0
CloseHandle hToken
End If
End If
Shutdown = CBool(ExitWindowsEx(Mode, Reason))
End Function
Авторы: |
||
| Предыдущий раздел | Следующий раздел |
| © 2004. При цитировании, пожалуйста, не забудьте поставить ссылку на оригинальную страницу. |