1

With AutoHotkey v2 I'm trying to put my computer to sleep using the sequence Win+x (to bring up the quick links menu), u (for "Shutdown…"), s (for "Sleep"). (If you know a better way to put the computer to sleep let me know, but this has been discussed extensively in other questions, and the recommended approach puts the computer into hibernate on my machine, not sleep, as explained elsewhere. So let's just stick with this scenario.)

Let's say I want to map this sequence to Win+z (for "zzzzzzz" for sleeping). This does not work:

#z::
{
  SendEvent "#xus"
}

This does not work either:

#z::
{
  SendEvent "#x"
  SendEvent "u"
  SendEvent "s"
}

This is the only approach that seems to work, sort of:

#z::
{
  SendEvent "#x u s"
}

It seems sort of finicky and doesn't always work. Sometimes it makes a system sound, as if an incorrect key was pressed. Moreover I don't know what the spaces mean: is AutoHotkey sending spaces, or is that merely a separator between keys to send? I used it by trial-and-error, and could find no documentation on what spaces even mean for AutoHotkey v2.

What's the best way to send the Win+x, u, s sequence in AutoHotkey v2 to achieve my goal of putting the computer to sleep via a "sleep" menu? (If there is a better, more easily achievable "sleep" menu I'd be interesting in knowing that as well.)

Garret Wilson
  • 18,219
  • 30
  • 144
  • 272

3 Answers3

3

Dieisson's suggestion to add a Sleep was helpful, but there are more details, including one tip I found at https://stackoverflow.com/a/71753607 . Using AutoHotkey v2, here is the best I've found so far.

#z::
{
  WinActivate "ahk_class Shell_TrayWnd"
  Send "#x"
  Sleep 100
  Send "us"
}
Garret Wilson
  • 18,219
  • 30
  • 144
  • 272
0

This work, no matter if hibernate enabled or not:

StandBy()

StandBy() {
    PID := ProcessExist()
    ; Get the handle of this script with PROCESS_QUERY_INFORMATION (0x0400):
    h := DllCall("OpenProcess", "UInt", 0x0400, "Int", false, "UInt", PID, "Ptr")
    ; Open an adjustable access token with this process (TOKEN_ADJUST_PRIVILEGES = 32):
    DllCall("Advapi32.dll\OpenProcessToken", "Ptr", h, "UInt", 32, "Ptr*", &t:=0)
    ti := Buffer(16, 0)  ; structure of privileges
    NumPut("UInt", 1, ti, 0)  ; one entry in the privileges array...
    ; Retrieves the locally unique identifier of the privilege:
    DllCall("Advapi32.dll\LookupPrivilegeValue", "Ptr", 0, "Str", "SeShutdownPrivilege", "Int64*", &luid:=0)
    NumPut("Int64", luid, ti, 4)
    NumPut("UInt", 2, ti, 12)  ; Enable this privilege: SE_PRIVILEGE_ENABLED = 2
    ; Update the privileges of this process with the new access token:
    r := DllCall("Advapi32.dll\AdjustTokenPrivileges", "Ptr", t, "Int", false, "Ptr", ti, "UInt", 0, "Ptr", 0, "Ptr", 0)
    DllCall("CloseHandle", "Ptr", t)  ; Close this access token handle to save memory.
    DllCall("CloseHandle", "Ptr", h)  ; Close this process handle to save memory.

    ;PC standby (S3)
    DllCall("ntdll\ZwInitiatePowerAction", "Int", 2, "Int", 4, "Int", 0x80000000, "Int", 1)
}
stealzy
  • 51
  • 4
  • But will this work if the S3 sleep state has been disabled (as is the case on some of the latest machines), and only the S0 "Modern Standby" state is available? See https://superuser.com/a/1739240 . – Garret Wilson Sep 11 '22 at 19:07
  • 1
    @GarretWilson I tried this script. My machine does not support S3. It went into Hibernate instead. – syockit May 02 '23 at 12:00
-1

You may try the following dll call, i cant test right now because im working..

DllCall("PowrProf\SetSuspendState", "Int", 0, "Int", 0, "Int", 0)

Documentation: https://learn.microsoft.com/en-us/windows/win32/api/powrprof/nf-powrprof-setsuspendstate

About the sequence, im actually not using AHK v2, but i think this should work:

#z::

Send "{LWIN Down}x{Lwin Up}"

Sleep 500 ; just to be sure that the menu is open

Send "us"

return

  • No, odles of pages have went round and round on how to go into sleep mode directly, but what you give about `SetSuspendState` doesn't work; if hibernate is enabled, it goes into hibernate mode instead. I'm trying to keep this question from being a rehash of incorrect methods to go into sleep mode, because that has been gone over again and again and again elsewhere, and they don't work. – Garret Wilson Aug 23 '22 at 20:01
  • 1
    Dieisson, the comment about `Sleep` was helpful, so I'll give you the bounty. `SetSuspendState` doesn't work with hibernate and [modern standby](https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/modern-standby), however. – Garret Wilson Aug 25 '22 at 15:27