?
Solved

Shutdown without poweroff - VB5 on Win98 original edition (ATX PC)

Posted on 2003-03-14
20
Medium Priority
?
580 Views
Last Modified: 2008-01-09
I would like to be able to programmatically (not shelling out to another program) shutdown an ATX-enabled PC in Win98 original edition via VB5. The following line using an API call to ExitWindowsEx *should* work as far as I can tell, based on documentation :

ret_val& = ExitWindowsEx(EWX_SHUTDOWN, 0&)

where EWX_SHUTDOWN is a const with value 1.

But this is shutting down PC and powering it off instead. Documentation says that you need to include the EWX_POWEROFF (value = 8) flag to poweroff the system [EWX_SHUTDOWN Or EWX_POWEROFF], but my system is shutting down without it, and that's not what I want.

How can I get the intended result?
0
Comment
Question by:asmcmrr
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 8
  • 2
  • +1
20 Comments
 
LVL 4

Assisted Solution

by:CareyJ
CareyJ earned 140 total points
ID: 8140418
Try InitiateSystemShutdown API Call

Private Declare Function InitiateSystemShutdown Lib "advapi32.dll" Alias "InitiateSystemShutdownA" (ByVal lpMachineName As String, ByVal lpMessage As String, ByVal dwTimeout As Long, ByVal bForceAppsClosed As Long, ByVal bRebootAfterShutdown As Long) As Long

0
 
LVL 1

Author Comment

by:asmcmrr
ID: 8140692
This is Windows 98 - not NT, not XP, not ME. Only Win32 API calls valid for Win98 are going to help...
0
 
LVL 1

Assisted Solution

by:GERTJAN
GERTJAN earned 160 total points
ID: 8144454
You can try the following line instead:

ExitWindowsEx (EWX_POWEROFF), &HFFFF
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 1

Author Comment

by:asmcmrr
ID: 8144707
For GERTJAN:

It doesn't work. Using it the way written actually seems to allow you to log off (you get the logon prompt) and log on again without stopping runnings programs, although that may only be the case because I logged back in as the same user.

I tried relevant variations keeping the &HFFFF, but they didn't work either. (EWX_SHUTDOWN; EWX_SHUTDOWN Or EWX_POWEROFF)
0
 
LVL 1

Accepted Solution

by:
GERTJAN earned 160 total points
ID: 8145831
asmcmrr,

I,am using in a program a module to shut down a pc and that,s working fine on all the opperating systems.

The code you using seems to be fine. Maybe you can try the module and see iff there is some thifferent.

Here,s the code:

 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 Const EWX_LogOff As Long = 0
      Private Const EWX_SHUTDOWN As Long = 1
      Private Const EWX_REBOOT As Long = 2
      Private Const EWX_FORCE As Long = 4
      Private Const EWX_POWEROFF As Long = 8

      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
      Private Declare Sub ExitWindowsDialog Lib "shell32.dll" Alias "#60" (ByVal hwndOwner As Long)
      Public Declare Function GetLastError Lib "kernel32" () As Long
      Public Const mlngWindows95 = 0
      Public Const mlngWindowsNT = 1
      Public glngWhichWindows32 As Long
      Public Declare Function GetVersion Lib "kernel32" () As Long
      Public Declare Sub SetLastError Lib "kernel32" _
         (ByVal dwErrCode As Long)

      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
 
Public Sub ShutDown()
    Dim lngVersion As Long
     lngVersion = GetVersion()

     If ((lngVersion And &H80000000) = 0) Then
         glngWhichWindows32 = mlngWindowsNT
     Else
         glngWhichWindows32 = mlngWindows95
     End If
     If glngWhichWindows32 = mlngWindowsNT Then
     AdjustToken
     End If
     Dim Retval As Long, MsgResult As Long
     DoEvents
     Retval = ExitWindowsEx(EWX_SHUTDOWN, 0&)

End Sub

Public Sub ReStart()
     Dim lngVersion As Long
     lngVersion = GetVersion()
     If ((lngVersion And &H80000000) = 0) Then
         glngWhichWindows32 = mlngWindowsNT
     Else
         glngWhichWindows32 = mlngWindows95
     End If
     If glngWhichWindows32 = mlngWindowsNT Then
     AdjustToken
     End If
     DoEvents
    ExitWindowsEx (EWX_FORCE), &HFFFF

End Sub
Public Sub ReBooT()
      Dim lngVersion As Long
     lngVersion = GetVersion()

     If ((lngVersion And &H80000000) = 0) Then
         glngWhichWindows32 = mlngWindowsNT
     Else
         glngWhichWindows32 = mlngWindows95
     End If
     If glngWhichWindows32 = mlngWindowsNT Then
     AdjustToken
     End If
     DoEvents
     ExitWindowsEx (EWX_REBOOT), &HFFFF
End Sub

Public Sub LogOf()
      Dim lngVersion As Long
     lngVersion = GetVersion()

     If ((lngVersion And &H80000000) = 0) Then
         glngWhichWindows32 = mlngWindowsNT
     Else
         glngWhichWindows32 = mlngWindows95
     End If
     If glngWhichWindows32 = mlngWindowsNT Then
     AdjustToken
     End If
     DoEvents
     ExitWindowsEx (EWX_LogOff), &HFFFF
End Sub

Public Sub PowerOf()
      Dim lngVersion As Long
     lngVersion = GetVersion()

     If ((lngVersion And &H80000000) = 0) Then
         glngWhichWindows32 = mlngWindowsNT
     Else
         glngWhichWindows32 = mlngWindows95
     End If
     If glngWhichWindows32 = mlngWindowsNT Then
     AdjustToken
     End If
     DoEvents
     ExitWindowsEx (EWX_POWEROFF), &HFFFF
End Sub

Public Sub CloseWindow(hWnd As Long)
     ExitWindowsDialog hWnd
End Sub



0
 
LVL 1

Author Comment

by:asmcmrr
ID: 8148088
For GERTJAN (#2):

Going back to your original comment (using the EWX_POWEROFF flag), I just want to make sure you know what I'm trying to do. I don't want to poweroff, just shutdown (and leave the "It is now okay to shut off your computer" screen up).

I tried using your module by pasting it into its very own projects and making a simple Sub Main() :

Sub Main()

ShutDown

End Sub

And it shutdown and poweroffed off the PC. :(

Just for reference, this is a Penitum4-2.0a (2Ghz) on an Asus P4S-533 motherboard.

---
ASM
0
 
LVL 4

Assisted Solution

by:CareyJ
CareyJ earned 140 total points
ID: 8148669
ExitWindowsEx is working that way because you have the Win98
"FastReboot" Option enabled on that computer.  You configured
your computer to bypass the "Its now safe to turn off" Win98
message.

Your VB program's API call can't override this user setting.  

If you've forgotten how you enabled the Fast Shutdown option
on that computer, do these steps to disable it and then your
API call to ExitWindowsEx will work like you want:
   1. Click Start, Programs, Accessories, System Tools
   2. Run System Information.
   3. On the Tools menu, click System Configuration Utility.
   4. On the General tab, click the Advanced Button.
   5. Click to check the "Disable Fast Shutdown" check box
   6. Click OK, and then click OK.
   7. Click "Yes" to restart your computer.

To make your function reliable on other Win98 computers, you may
want to programmatically check the registry value for "FastReboot"  
prior to making your API call.  If the value is "1", your function
will cause the computer to shutdown completely.  I don't recommend
programmatically changing the value for the user just so your
program works correctly.

The "FastReboot" value is in the following registry key:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Shutdown
0
 
LVL 1

Author Comment

by:asmcmrr
ID: 8149158
CareyJ:

Actually, I already had fast shutdown disabled. I re-enabled it to be thorough when testing GERTJAN's code, and it didn't work either way.
0
 
LVL 4

Assisted Solution

by:CareyJ
CareyJ earned 140 total points
ID: 8149560
ExitWindowsEx is working that way because you have the Win98
"FastReboot" Option enabled on that computer.  You configured
your computer to bypass the "Its now safe to turn off" Win98
message.

Your VB program's API call can't override this user setting.  

If you've forgotten how you enabled the Fast Shutdown option
on that computer, do these steps to disable it and then your
API call to ExitWindowsEx will work like you want:
   1. Click Start, Programs, Accessories, System Tools
   2. Run System Information.
   3. On the Tools menu, click System Configuration Utility.
   4. On the General tab, click the Advanced Button.
   5. Click to check the "Disable Fast Shutdown" check box
   6. Click OK, and then click OK.
   7. Click "Yes" to restart your computer.

To make your function reliable on other Win98 computers, you may
want to programmatically check the registry value for "FastReboot"  
prior to making your API call.  If the value is "1", your function
will cause the computer to shutdown completely.  I don't recommend
programmatically changing the value for the user just so your
program works correctly.

The "FastReboot" value is in the following registry key:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Shutdown
0
 
LVL 4

Expert Comment

by:CareyJ
ID: 8149605
I just tried it on my test stand.  With FastReboot "ON", ExitWindowsEx makes the PC shutdown completely, bypassing the "It's safe to ..." screen.  When I set FastReboot "OFF", ExitWindowsEx drops the PC to the "It's safe to..." screen.

Obviously, this problem is with the PC or it's Win98 installation/options.  Have you tried your program on another Win98 box to see how it works for the rest of us in Win98?

Also, go to Microsoft.com and search for "Win98 Shutdown Supplement".  Download the Supplement and run it on that computer.  The supplement fixes many Shutdown issues in Win98.
0
 
LVL 1

Author Comment

by:asmcmrr
ID: 8149794
The shutdown supplement is for Win98 SE only. I have Win98 original edition. My only other ATX-Win98 PC is running a near identical setup. Pentium4 Celeron on Asus P4S533-E motherboard. I will try it out.
0
 
LVL 1

Author Comment

by:asmcmrr
ID: 8149947
I tried it on the other computer and it doesn't work either I'm afraid, same result. (I tried it with fast shutdown enabled and disabled)
0
 
LVL 4

Expert Comment

by:CareyJ
ID: 8150227
Do those PC's stop at the "It's safe to..." screen when you click Start/Shutdown?
0
 
LVL 1

Author Comment

by:asmcmrr
ID: 8157000
For a second, then they turn off.
0
 
LVL 4

Expert Comment

by:CareyJ
ID: 8157216
Then it's not a API call problem.  It's a Windows Shutdown configuration.  This could also be a delay = 0 for "Wait time" at the "safe to turn off" screen.

I've seen a shareware utility named TweakUI that, among many performance enhancing registry changes, one option could configure Win98 to skip through the "Safe to turn off" screen.  Has someone ran TweakUI on those machines?

Also, check your bios settings for a motherboard shutdown method. Options here, if your bios has it, are something like:
1) Manual    <---This pauses for user intervention
2) Restart   <---This simulates a "Reset" Button press
2) Poweroff  <---This simulates a "Power" Button press

If you remain stumped, you might have better luck asking this question in the OS/Win98 Topic Area.  It's a classic configuration problem.
0
 
LVL 1

Author Comment

by:asmcmrr
ID: 8160945
I have TweakUI and have used it for a long time. The Win9x versions don't have any wait time settings for shutdown. There is a bootdelay option, but that's for startup, not shutdown. My bios (Award) doesn't have any shutdown configuration beyond picking what holding in the start button for > 4 seconds will do. (Soft Poweroff or Suspend)
0
 
LVL 4

Expert Comment

by:CareyJ
ID: 8163655
Well, the problem isn't in the API call.  You're asking why the PC doesn't stop at Logo.sys when you call ExitWindowsEx when it doesn't even do that in a normal shutdown.  ExitWindowsEx doesn't change your shutdown options, it executes them.

Did you check your Bios' APM options to see if there is a "poweroff" shutdown option that is enabled?

Maybe you could try ExitWindowsEx with both Bios and Win98 APM options disabled.

0
 
LVL 1

Author Comment

by:asmcmrr
ID: 8164325
Unfortunately, the BIOS doesn't have much of anything for APM beyond the "soft off" or "suspend" options. I know for sure that the API call is good, I used rundll to execute it by copying and pasting code right from Microsoft's K.B. on the subject. I've tried all Windows options I can think of, unless someone can point out a different one nothing's going to change. I think posting this to the "Win98" area is a good idea though? Can I "move" this question there since it isn't answered yet or do I have to post a new one?
0
 
LVL 4

Expert Comment

by:CareyJ
ID: 8164492
You'll have to post another one.

If you get an answer, come back to this one and post the answer here too.
0
 

Expert Comment

by:CleanupPing
ID: 8900062
asmcmrr:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
Experts: Post your closing recommendations!  Who deserves points here?
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…
Suggested Courses

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question