• Recent Posts

  • Meta

  • Tags

    autocomplete benchmark data cpu cycles directory exists disable beep on enter doevents ebook excel extensions file exists getinputstate gzip high cpu usage intensive task left edge linq mcisendstring microsoft msdn no doevents office open webpage play mp3 play wave right edge scroll textbox shell show icon show notify icon source stop beep on enter system tray text tar textbox text in system tray time consuming tutorials vb 2008 video visual basic.net visual basic 2005 visual studio visual studio 2005 ehancements vs 2005 IDE extensions windows mci
  • « Import Namespaces to save Time and writing Less code | Home | Display Text in the System Tray/Notify Icon in VB.NET »

    Why simply calling ExitWindowsEx won’t Shutdown/Restart the Computer.?.(Update: VB 6.0 Code Links Added)

    By Jason | November 6, 2007

    Click Star to Rate Post
    1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5 out of 5)
    Loading ... Loading ...


       
    Bookmark and Share

       


     
      This question is a very popular one. The ExitWindowsEx question works perfectly fine if using the older versions of Windows like Windows 98 or ME with no special codes to use. You only needed to call the ExitWindowsEx API with the desired parameters and it was good to go. But Kernel changes and such took place with the newer versions of Windows like Windows 2000 and Windows XP. Microsoft now requires that your application have 'certain privileges' before it will grant your applications shutdown/restart/logoff request. Visual C++ has these Privileges by default, but not any of the VBs unfortunately. So, the first step you must do is give your application special privileges. Below is some VB 6.0 code from Microsoft that I converted to Visual Basic .NET. The code here will work with all versions of .NET including 2005 and 2008. There are only minor changes needed to make it work with Visual Basic 5.0/6.0, mainly the variable/parameter types like converting Integers to Long types. IF it didn't take so much code I would post the .NET and VB 6.0 versions of the code. But I will just go ahead and put the VB.NET versions.

       

    Note: If you are wanting to get the VB 5.0 and VB 6.0 privilege codes then click on this link and/or click this link as well.

       

      First setup some structures for the APIs.

       

    __________________

       

    '

    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

       

       

    __________________

       

       

    Next you can go ahead and add the API methods to execute the privilege requests.

       

    '

    '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

       

    ______________________

       

    Now to setup and create a Sub that will do all the work to set the privileges.

       

    __________________

        

    '

    '

    '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.

        AdjustTokenPrivileges(hdlTokenHandle, False, tkp, Len(tkpNewButIgnored), tkpNewButIgnored, lBufferNeeded)

       

    End Sub

       

    __________________

       

      Now that the Privilege codes are done, you just need to call the above Function before the shutdown code. Below is the API call to shutdown/restart/ect.. the computer...

       

    __________________

        

    '

    '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

       

    __________________

       

      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.

    ExitWindowsEx(shutdownType, Nothing)

       

       

    ______________________

        

       

      Thats all there is to it! OK, it Is alot of code to get the ExitWindowsEx API to work with Windows 2000/XP/Vista. To bad Microsoft doesn't give Visual Basic these Privileges by Default like they do with C++. Oh well, don't have much of a choice when using VB.

      Remember, its possible to get these codes to work with Visual Basic 5.0 and 6.0 as well. You need to change the types (Especially Integers to Longs, and Structures to Types) plus process info then it should be ok.

      I have pre-made Class Libraries, and Examples for Visual Basic.NET 2002/2003/2005/2008 and I have a Example of doing this in Visual Basic 5.0/6.0 at my Visual Basic Code Source website.

       

    Well thats all for now. Have Fun!

       

                        Jason

     


     

    Popularity: 14% [?]

    Topics: - (.5.0/6.0), - (.5.0/6.0), - (.NET All + 05/08), - (.NET All + 05/08), - .All VB (Related to All), .All VB (Related to All) |

    3 Responses to “Why simply calling ExitWindowsEx won’t Shutdown/Restart the Computer.?.(Update: VB 6.0 Code Links Added)”

    1. Unni Raj Says:
      January 18th, 2008 at 9:14 am

      Hi Thank you very much

    2. Pablo Says:
      June 8th, 2008 at 12:33 am

      thanks, it works great on vb2005 .net 2.0

    3. garry b Says:
      December 12th, 2008 at 5:41 pm

      thanks the codes needed are
      Private Const EWX_LOGOFF As Integer = &H0
      Private Const EWX_SHUTDOWN As Integer = &H1
      Private Const EWX_REBOOT As Integer = &H2
      Private Const EWX_FORCE As Integer = &H4
      Private Const EWX_POWEROFF As Integer = &H8
      Private Const EWX_FORCEIFHUNG As Integer = &H10 '2000/XP only

    Comments