Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 | 2 |

 

  Вопрос: Функция ExitWindowsEx Добавлено: 10.09.05 19:52  

Автор вопроса:  Vit | Web-сайт: www.home-soft.jino-net.ru
Почему не работает функция ExitWindowsEx?
Код программы:

Public Function IsWinNT() As Boolean
    Dim myOS As OSVERSIONINFO
    myOS.dwOSVersionInfoSize = Len(myOS)
    GetVersionEx myOS
    IsWinNT = (myOS.dwPlatformId = VER_PLATFORM_WIN32_NT)
End Function
'set the shut down privilege for the current application
Private Sub EnableShutDown()
    Dim hProc As Long
    Dim hToken As Long
    Dim mLUID As LUID
    Dim mPriv As TOKEN_PRIVILEGES
    Dim mNewPriv As TOKEN_PRIVILEGES
    hProc = GetCurrentProcess()
    OpenProcessToken hProc, TOKEN_ADJUST_PRIVILEGES + TOKEN_QUERY, hToken
    LookupPrivilegeValue "", "SeShutdownPrivilege", mLUID
    mPriv.PrivilegeCount = 1
    mPriv.Privileges(0).Attributes = SE_PRIVILEGE_ENABLED
    mPriv.Privileges(0).pLuid = mLUID
    ' enable shutdown privilege for the current application
    AdjustTokenPrivileges hToken, False, mPriv, 4 + (12 * mPriv.PrivilegeCount), mNewPriv, 4 + (12 * mNewPriv.PrivilegeCount)
End Sub
' Shut Down NT
Public Sub ShutDownNT(Force As Boolean)
    Dim Flags As Long
    Flags = EWX_SHUTDOWN
    If Force Then Flags = Flags + EWX_FORCE
    If IsWinNT Then EnableShutDown
    ExitWindowsEx Flags, 0
End Sub

Для NT платформ необходимо получить привилегии для управления питанием (Shutdown, Reboot, Logoff) - EnableShutDown.
Когда срабатывает событие в программе, то комп действует одним из следующих методов:
 - никак не реагирует
 - завершает работу Windows, но показывает сообщение "Теперь питание компьютера можно отключить".
Раньше такого не замечал. Машина работает по Win2000. Тестировал под Win98 и WinXP - работает нормально. Что за глюки?

Кто знает в чём ошибка и как её исправить?

Ответить

  Ответы Всего ответов: 17  

Номер ответа: 1
Автор ответа:
 sne



Разработчик Offline Client

ICQ: 233286456 

Вопросов: 34
Ответов: 5445
 Web-сайт: hw.t-k.ru
 Профиль | | #1
Добавлено: 11.09.05 01:46
попробуй сравнить с этим:

    Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long
    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" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, lpLuid As LUID) As Long
    Private Declare Function AdjustTokenPrivileges Lib "advapi32" (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 SetSystemPowerState Lib "kernel32" (ByVal fSuspend As Long, ByVal fForce As Long) As Long
    Private Declare Function OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
    
    Private Const SE_SHUTDOWN_NAME = "SeShutdownPrivilege"
    Private Const SE_PRIVILEGE_ENABLED = &H2
    Private Const ANYSIZE_ARRAY = 1
    Private Const ERROR_SUCCESS = 0&
    
    Private Const VER_PLATFORM_WIN32s = 0
    Private Const VER_PLATFORM_WIN32_WINDOWS = 1
    Private Const VER_PLATFORM_WIN32_NT = 2

    Private Const EWX_LOGOFF = &H0&      ' завершение сеанса пользователя
    Private Const EWX_SHUTDOWN = &H1&     ' шатдаун компьютера
    Private Const EWX_REBOOT = &H2&       ' перезагрузка компьютера
    Private Const EWX_POWEROFF = &H8&     ' выключение компьютера (ATX)
    Private Const EWX_FORCE = &H4&        ' флаг принудительного выполнения операции
    Private Const EWX_FORCEIFHUNG = &H10& ' флаг принудительного выполнения при зависании

    Private Type LUID
        UsedPart As Long: IgnoredForNowHigh32BitPart As Long
    End Type
    Private Type LUID_AND_ATTRIBUTES
        TheLuid As LUID: Attributes As Long
    End Type
    Private Type TOKEN_PRIVILEGES
        PrivilegeCount As Long: TheLuid As LUID: Attributes As Long
    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

Public Function OsVersion(Back As Integer) As String
    Dim info As OSVERSIONINFO
    info.dwOSVersionInfoSize = Len(info)
    GetVersionEx info
    If Back = 0 Then OsVersion = CInt(info.dwPlatformId)
    If Back = 1 Then
        Select Case info.dwPlatformId
            Case 0
                OsVersion = ""
            Case 1
                OsVersion = "Windows 9x" & " v" & info.dwMajorVersion & "."
                OsVersion = OsVersion & info.dwMinorVersion & " Build "
                OsVersion = OsVersion & info.dwBuildNumber
            Case 2
                OsVersion = "Windows NT" & " v" & info.dwMajorVersion & "."
                OsVersion = OsVersion & info.dwMinorVersion & " Build "
                OsVersion = OsVersion & info.dwBuildNumber
        End Select
    End If
    If Back = 3 Then OsVersion = info.dwMajorVersion
    Back = 0
End Function

Public Function Shutdown() As Boolean
    Select Case OsVersion(False)
        Case Is = VER_PLATFORM_WIN32s
            Shutdown = False
        Case Is = VER_PLATFORM_WIN32_WINDOWS
            ExitWindowsEx EWX_SHUTDOWN, 0&
            Shutdown = True
        Case Is = VER_PLATFORM_WIN32_NT
            AdjustToken
            ExitWindowsEx EWX_SHUTDOWN Or EWX_POWEROFF, 0
            Shutdown = True
    End Select
End Function

Public Function Restart() As Boolean
    Select Case OsVersion(False)
        Case Is = VER_PLATFORM_WIN32s
            Restart = False
        Case Is = VER_PLATFORM_WIN32_WINDOWS
            ExitWindowsEx EWX_REBOOT, 0&
            Restart = True
        Case Is = VER_PLATFORM_WIN32_NT
            AdjustToken
            ExitWindowsEx EWX_REBOOT, 0
            Restart = True
    End Select
End Function

Public Sub LogOff()
    ExitWindowsEx EWX_LOGOFF, 0&
End Sub

Public Sub Suspend()
    If OsVersion(False) = VER_PLATFORM_WIN32_NT Then AdjustToken
    SetSystemPowerState True, False
End Sub

Public Sub Hibernate()
    If OsVersion(False) = VER_PLATFORM_WIN32_NT Then AdjustToken
    SetSystemPowerState False, False
End Sub

Private Function AdjustToken() As Long
    Const TOKEN_ADJUST_PRIVILEGES = &H20: Const TOKEN_QUERY = &H8
    
    Dim hdlProcessHandle As Long, hdlTokenHandle As Long, lBufferNeeded As Long
    Dim tmpLuid As LUID: Dim tkp As TOKEN_PRIVILEGES
    Dim tkpNewButIgnored As TOKEN_PRIVILEGES
    
    hdlProcessHandle = GetCurrentProcess()
    OpenProcessToken hdlProcessHandle, (TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY), hdlTokenHandle
    LookupPrivilegeValue "", "SeShutdownPrivilege", tmpLuid
    tkp.PrivilegeCount = 1
    tkp.TheLuid = tmpLuid
    tkp.Attributes = SE_PRIVILEGE_ENABLED
    AdjustTokenPrivileges hdlTokenHandle, False, tkp, Len(tkpNewButIgnored), tkpNewButIgnored, lBufferNeeded
End Function

Ответить

Номер ответа: 2
Автор ответа:
 «UL.eXe»



ICQ: 197.895.916.247 

Вопросов: 72
Ответов: 540
 Профиль | | #2 Добавлено: 11.09.05 23:06
ExitWindowsEx под NT, XP не работает.
Код который написал sne подходит, но всеже:

Dim strComputer As String
strComputer = "."
Set objWMIService = GetObject("winmgmts:" & _
"{impersonationLevel=impersonate,(Shutdown)}!\\" & strComputer & "\root\cimv2";)
Set colOperatingSystems = objWMIService.ExecQuery( _
"Select * from Win32_OperatingSystem";)
For Each ObjOperatingSystem In colOperatingSystems
ObjOperatingSystem.ShutDown 'Для выключения
Next


помоему покороче будет =)

Ответить

Номер ответа: 3
Автор ответа:
 AndreyMp



ICQ: 237822510 

Вопросов: 28
Ответов: 1182
 Профиль | | #3 Добавлено: 12.09.05 09:16
Это конечно короче, но под 98-й не пойдет. Там по моему WMI еще нет.

Ответить

Номер ответа: 4
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #4 Добавлено: 12.09.05 12:12
для 98 sne привёл пример

Ответить

Номер ответа: 5
Автор ответа:
 Vit



Вопросов: 68
Ответов: 62
 Web-сайт: www.home-soft.jino-net.ru
 Профиль | | #5
Добавлено: 12.09.05 13:34
Я конечно попробую все варианты, но меня удивляет тот факт, что раньше надругих машинах, работающих по Win2000 программа работала. Та тачка, на которой я пытался сделать - специально cконфигурирована для некоторой задачи (в ней даже CD-ROM'а нет), т.е. вмешательство в работу компа ограничена.

Ответить

Номер ответа: 6
Автор ответа:
 «UL.eXe»



ICQ: 197.895.916.247 

Вопросов: 72
Ответов: 540
 Профиль | | #6 Добавлено: 12.09.05 13:34
Это конечно короче, но под 98-й не пойдет. Там по моему WMI еще нет

Написал, Протестировал. Работает вроде на 98 и XP


Private Declare Function ExitWindowsEx Lib "user32" _
(ByVal uFlags As Long, _
ByVal dwReserved As Long) As Long


Dim retval  As Long
retval = ExitWindowsEx(8, 0) 'выключил

Dim retval As Long
retval = ExitWindowsEx(2, 0) 'перезагрузил

Dim retval As Long
retval = ExitWindowsEx(4, 0) закрыл все програмы

Dim retval As Long
retval = ExitWindowsEx(0, 0)  'завершил тек.юзера

Ответить

Номер ответа: 7
Автор ответа:
 AndreyMp



ICQ: 237822510 

Вопросов: 28
Ответов: 1182
 Профиль | | #7 Добавлено: 12.09.05 14:28
Код описанный в вопросе рабочий (пример из API-Guide). Насколько я понял проблема состоит лишь в небольшой доработке под корпус ATX. Добавьте
Private Const EWX_POWEROFF = &H8&
, как писал sne и процедурка ShutDownNT примет следующий вид:
Public Sub ShutDownNT(Force As Boolean)
    Dim Flags As Long
    Flags = EWX_SHUTDOWN Or EWX_POWEROFF
    If Force Then Flags = Flags + EWX_FORCE
    If IsWinNT Then EnableShutDown
    ExitWindowsEx Flags, 0
End Sub

Все.Проверьте.

Ответить

Номер ответа: 8
Автор ответа:
 sne



Разработчик Offline Client

ICQ: 233286456 

Вопросов: 34
Ответов: 5445
 Web-сайт: hw.t-k.ru
 Профиль | | #8
Добавлено: 12.09.05 15:14
2VB Lamer, к прмеру у меня служба WMI отключена - так что твой код бреется :P

2HACKER, это для 2к/XP подходит не хуже!

Ответить

Номер ответа: 9
Автор ответа:
 LamerOnLine



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #9 Добавлено: 12.09.05 17:00
Насколько я понял проблема состоит лишь в небольшой доработке под корпус ATX.

Ну, быть может проблема кроется несколько глубже - в доработке самого корпуса под стандарт ATX. Это объясняет почему код на 98 не работает :)))

Ответить

Номер ответа: 10
Автор ответа:
 AndreyMp



ICQ: 237822510 

Вопросов: 28
Ответов: 1182
 Профиль | | #10 Добавлено: 12.09.05 17:37
Ну, быть может проблема кроется несколько глубже - в доработке самого корпуса под стандарт ATX. Это объясняет почему код на 98 не работает :)))


Тестировал под Win98 и WinXP - работает нормально.
- цитата из вопроса для LamerOnLine, или Вы имели ввиду код VBLamer? Но sne уже объяснил, почему его не стоит рассматривать.
Мой ответ лишь результат сравнения кода, приведенного в вопросе и кода sne(как и предлагалось).

Ответить

Номер ответа: 11
Автор ответа:
 «UL.eXe»



ICQ: 197.895.916.247 

Вопросов: 72
Ответов: 540
 Профиль | | #11 Добавлено: 12.09.05 23:39
2sne:

Private Declare Function ExitWindowsEx Lib "user32" _
(ByVal uFlags As Long, _
ByVal dwReserved As Long) As Long


Чуть выше, чем твой ответ ^

зы:
ну и при чем сдесь WMI, сдесь user32.dll
    роль играет, который если я не ошибаюсь есть
    на (почти) всех мастдаях =)

Ответить

Номер ответа: 12
Автор ответа:
 «UL.eXe»



ICQ: 197.895.916.247 

Вопросов: 72
Ответов: 540
 Профиль | | #12 Добавлено: 13.09.05 01:06
2Андрей:

Тестировал под Win98 и WinXP - работает нормально.


А, спасибо Адрей, что-то я невнимательный.
ps Работа видимо замучала..

Ответить

Номер ответа: 13
Автор ответа:
 AndreyMp



ICQ: 237822510 

Вопросов: 28
Ответов: 1182
 Профиль | | #13 Добавлено: 13.09.05 09:12
Что то автора вопроса не видно,наверно сделал ShutDown навсегда.

Ответить

Номер ответа: 14
Автор ответа:
 sne



Разработчик Offline Client

ICQ: 233286456 

Вопросов: 34
Ответов: 5445
 Web-сайт: hw.t-k.ru
 Профиль | | #14
Добавлено: 13.09.05 09:52
2VB Lamer, глянь выше и ты увидишь свой ответ:

ExitWindowsEx под NT, XP не работает.
Код который написал sne подходит, но всеже:


но все же у мня WMI отключена.

Чуть выше, чем твой ответ ^

А этот - максимум перезагрузит или выйдет из сеанса, т.к. ты не получаешь привелегий.

Хватит флэймить...

Ответить

Номер ответа: 15
Автор ответа:
 Александр



Разработчик Offline Client

ICQ: 204034 

Вопросов: 106
Ответов: 1919
 Профиль | | #15 Добавлено: 13.09.05 14:51
ну и при чем сдесь WMI, сдесь user32.dll
роль играет, который если я не ошибаюсь есть
на (почти) всех мастдаях

А на каких нету? :))

Ответить

Страница: 1 | 2 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам