Visual Basic > Visual Basic Forums > Visual Basic Language > exitwindowsex: check which options are supported on the users system
Ask a questionAsk a question
 

Answerexitwindowsex: check which options are supported on the users system

  • Tuesday, October 27, 2009 5:48 PMfamlam Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I use ExitWindowsEx to shut down/reboot computers, or log off users.

    But when I tried to use the 'reboot and restart applications' (0x00000040) parameter my computer (Vista) just logged off...
    An other check on a Windows 98: as well the reboot and restart apps as the 'shutdown and poweroff' (0x00000008) resulted in a logoff. 
    From this I concluded that the system just logs off when it does not recognize the command given. 

    For this reason (and an other: that I can inform the user that method X is not supported) I was wondering: is there any way to get all supported shutdown/reboot/logoff parameters of the system?

Answers

  • Thursday, October 29, 2009 8:01 AMJeff ShanMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code

    Hi famlam,

    What's the return value of the api calling? This maybe a priveledge problem. To shut down or restart the system, the calling process must use the AdjustTokenPrivileges function to enable the SE_SHUTDOWN_NAME privilege. Most of the privilege is disabled for the user account by default. You have to use AdjustTokenPrivileges to enable it explicitly. 
    You can try the following code, it works well on my computer

    Public Class Form1
    
        Private Structure LUID
            Dim UsedPart As Integer
            Dim IgnoredForNowHigh32BitPart As Integer
        End Structure
    
        Private Structure TOKEN_PRIVILEGES
            Dim PrivilegeCount As Integer
            Dim TheLuid As LUID
            Dim Attributes As Integer
        End Structure
    
        'The API functions below are all used to give the application the proper privilege so the OS will allow the app to Shutdown Windows.
        Private Declare Function OpenProcessToken Lib "advapi32" (ByVal ProcessHandle As IntPtr, ByVal DesiredAccess As Integer, ByRef TokenHandle As Integer) As Integer
        Private Declare Function LookupPrivilegeValue Lib "advapi32" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, ByRef lpLuid As LUID) As Integer
        Private Declare Function AdjustTokenPrivileges Lib "advapi32" (ByVal TokenHandle As Integer, ByVal DisableAllPrivileges As Boolean, ByRef NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Integer, ByRef PreviousState As TOKEN_PRIVILEGES, ByRef ReturnLength As Integer) As Integer
    
        'This sub will do all of the work of setting up your apps process using the APIs posted above to get the proper privileges to shutdown the OS. I originally got this function from msdn and converted it from VB 6.0 to VB.Net and did a tweak here and there.
        Private Sub AdjustToken()
            Const TOKEN_ADJUST_PRIVILEGES As Int32 = &H20
            Const TOKEN_QUERY As Int32 = &H8
            Const SE_PRIVILEGE_ENABLED As Int32 = &H2
            Dim hdlProcessHandle As IntPtr
            Dim hdlTokenHandle As Int32
            Dim tmpLuid As LUID
            Dim tkp As TOKEN_PRIVILEGES
            Dim tkpNewButIgnored As TOKEN_PRIVILEGES
            Dim lBufferNeeded As Int32
            hdlProcessHandle = Process.GetCurrentProcess.Handle
            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.
            Dim retval As Int32
            retval = AdjustTokenPrivileges(hdlTokenHandle, False, tkp, Len(tkpNewButIgnored), tkpNewButIgnored, lBufferNeeded)
            If (retval = 0) Then
                MessageBox.Show(System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString())
            End If
        End Sub
    
        'The function used to actually send the request to shutdown windows. Set the 'shutdownTypes' parameter to whether you want windows to "shutdown, reboot, logOff, ect..."
        Private Declare Function ExitWindowsEx Lib "user32" (ByVal shutdownType As Integer, ByVal dwReserved As Integer) As Integer
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            'To shutdown, restart, or logoff the computer you only need to call the AdjustToken() - Sub before the ExitWindowsEx code.
            AdjustToken()
            'Calls the function to begin executing.
            Dim retval As Int32
            retval = ExitWindowsEx(2 + 4, Nothing)
            If (retval = 0) Then
                MessageBox.Show(System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString())
            End If
        End Sub
    
    End Class
    

    I found it at this page.

    Hope this helps

    Regards
    Jeff Shan


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

All Replies

  • Thursday, October 29, 2009 8:01 AMJeff ShanMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code

    Hi famlam,

    What's the return value of the api calling? This maybe a priveledge problem. To shut down or restart the system, the calling process must use the AdjustTokenPrivileges function to enable the SE_SHUTDOWN_NAME privilege. Most of the privilege is disabled for the user account by default. You have to use AdjustTokenPrivileges to enable it explicitly. 
    You can try the following code, it works well on my computer

    Public Class Form1
    
        Private Structure LUID
            Dim UsedPart As Integer
            Dim IgnoredForNowHigh32BitPart As Integer
        End Structure
    
        Private Structure TOKEN_PRIVILEGES
            Dim PrivilegeCount As Integer
            Dim TheLuid As LUID
            Dim Attributes As Integer
        End Structure
    
        'The API functions below are all used to give the application the proper privilege so the OS will allow the app to Shutdown Windows.
        Private Declare Function OpenProcessToken Lib "advapi32" (ByVal ProcessHandle As IntPtr, ByVal DesiredAccess As Integer, ByRef TokenHandle As Integer) As Integer
        Private Declare Function LookupPrivilegeValue Lib "advapi32" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, ByRef lpLuid As LUID) As Integer
        Private Declare Function AdjustTokenPrivileges Lib "advapi32" (ByVal TokenHandle As Integer, ByVal DisableAllPrivileges As Boolean, ByRef NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Integer, ByRef PreviousState As TOKEN_PRIVILEGES, ByRef ReturnLength As Integer) As Integer
    
        'This sub will do all of the work of setting up your apps process using the APIs posted above to get the proper privileges to shutdown the OS. I originally got this function from msdn and converted it from VB 6.0 to VB.Net and did a tweak here and there.
        Private Sub AdjustToken()
            Const TOKEN_ADJUST_PRIVILEGES As Int32 = &H20
            Const TOKEN_QUERY As Int32 = &H8
            Const SE_PRIVILEGE_ENABLED As Int32 = &H2
            Dim hdlProcessHandle As IntPtr
            Dim hdlTokenHandle As Int32
            Dim tmpLuid As LUID
            Dim tkp As TOKEN_PRIVILEGES
            Dim tkpNewButIgnored As TOKEN_PRIVILEGES
            Dim lBufferNeeded As Int32
            hdlProcessHandle = Process.GetCurrentProcess.Handle
            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.
            Dim retval As Int32
            retval = AdjustTokenPrivileges(hdlTokenHandle, False, tkp, Len(tkpNewButIgnored), tkpNewButIgnored, lBufferNeeded)
            If (retval = 0) Then
                MessageBox.Show(System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString())
            End If
        End Sub
    
        'The function used to actually send the request to shutdown windows. Set the 'shutdownTypes' parameter to whether you want windows to "shutdown, reboot, logOff, ect..."
        Private Declare Function ExitWindowsEx Lib "user32" (ByVal shutdownType As Integer, ByVal dwReserved As Integer) As Integer
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            'To shutdown, restart, or logoff the computer you only need to call the AdjustToken() - Sub before the ExitWindowsEx code.
            AdjustToken()
            'Calls the function to begin executing.
            Dim retval As Int32
            retval = ExitWindowsEx(2 + 4, Nothing)
            If (retval = 0) Then
                MessageBox.Show(System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString())
            End If
        End Sub
    
    End Class
    

    I found it at this page.

    Hope this helps

    Regards
    Jeff Shan


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
  • Saturday, November 07, 2009 9:49 PMfamlam Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code

    Hi famlam,

    What's the return value of the api calling? This maybe a priveledge problem. To shut down or restart the system, the calling process must use the AdjustTokenPrivileges function to enable the SE_SHUTDOWN_NAME privilege. Most of the privilege is disabled for the user account by default. You have to use AdjustTokenPrivileges to enable it explicitly. 
    You can try the following code, it works well on my computer

    [...]

    I found it at this page.

    Hope this helps

    Regards
    Jeff Shan

    Thanks, it helps a lot. Forcing it can be done by using ExitWindowsEx(2 Or &H4, Nothing)
  • Friday, November 13, 2009 3:42 PMfamlam Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    But this part of my question isn't solved yet: 

    But when I tried to use the 'reboot and restart applications' (0x00000040) parameter my computer (Vista) just logged off...
    An other check on a Windows 98: as well the reboot and restart apps as the 'shutdown and poweroff' (0x00000008) resulted in a logoff. 
    From this I concluded that the system just logs off when it does not recognize the command given. 

    For this reason (and an other: that I can inform the user that method X is not supported) I was wondering: is there any way to get all supported shutdown/reboot/logoff parameters of the system?

    any ideas?