Newsgroup: it.comp.lang.visual-basic
Titolo: [?]ExitWindowsEx()

Come si può fare per chiudere la sessione windows sotto NT 4.0?
Ho provaro con ExitWindowsEx(), ma se uso EWX_POWEROFF o EWX_SHUTDOWN non
funziona, e la GetLastError() mi ritorna
1314 =  ERROR_PRIVILEGE_NOT_HELD
A required privilege is not held by the client.
Quale può essere la soluzione del problema?
Grazie a tutti.

Preso da MSDN...
CAUSE
In order to programmatically reboot a Windows NT system, the process
requires the SE_SHUTDOWN_NAME privilege. By default, Visual Basic
applications do not have this privilege and therefore will not reboot the
machine.
RESOLUTION
In order to get ExitWindowsEx API to reboot the system under Windows NT, the
SE_SHUTDOWN_NAME privilege must be set. The steps below describe how to get
the ExitWindowsEx API to work under Windows NT.
Step By Step Example
Create a new standard EXE in Visual Basic. Form1 is created by default.
View the code for Form1. In the Declarations section, add the following
code:
      Private Type LUID
         UsedPart As Long
         IgnoredForNowHigh32BitPart As Long
      End Type
      Private Type TOKEN_PRIVILEGES
        PrivilegeCount As Long
        TheLuid As LUID
        Attributes As Long
      End Type
      Private Const EWX_SHUTDOWN As Long = 1
      Private Const EWX_FORCE As Long = 4
      Private Const EWX_REBOOT = 2
      Private Declare Function ExitWindowsEx Lib "user32" (ByVal _
           dwOptions As Long, ByVal dwReserved As Long) As Long
      Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
      Private Declare Function OpenProcessToken Lib "advapi32" (ByVal _
         ProcessHandle As Long, _
         ByVal DesiredAccess As Long, TokenHandle As Long) 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
Add a procedure called AdjustToken with the following code:
      Private Sub AdjustToken()
         Const TOKEN_ADJUST_PRIVILEGES = &H20
         Const TOKEN_QUERY = &H8
         Const SE_PRIVILEGE_ENABLED = &H2
         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.TheLuid = tmpLuid
         tkp.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
Add a CommandButton to the form. In the Click event, add the following code:
      Private Sub Command1_Click()
         AdjustToken
         ExitWindowsEx (EWX_SHUTDOWN Or EWX_FORCE Or EWX_REBOOT), &HFFFF
      End Sub
Save the project and build an executable. When you run the executable and
click the CommandButton the computer will reboot as expected.
Ciao
Corrado