Hotkeys stop working after some time with 32-bit AHK on 64bit OS

Report problems with documented functionality
2_05
Posts: 31
Joined: 09 May 2018, 10:28

Hotkeys stop working after some time with 32-bit AHK on 64bit OS

Post by 2_05 » 16 Oct 2020, 15:56

[Moderator note: Moved topic from “Ask for Help” after it was concluded that this is a bug]

I have a script that was working fine on Windows 7, but since switching to a new laptop with Windows 10 quite some time ago the hotkeys stop working after some time and I have to restart the script.

I found that with the script below I can trigger the issue. On my laptop hotkeys will stop working with the script below after pressing Ctrl every second for 10 to 20 seconds. The script stops responding to hotkeys and key presses stop showing in the Keyhistory. My understanding is that this is due to the #If (Expression) being too slow. A simple solution is to add #IfTimeout 50.

EDIT: I just tried the same script on a different Windows 10 computer and the problem does not show up there. It seems to by a system specific issue but I have no idea what to look for in the system to fix it.
EDIT2: The issue seems to be happening specifically with AHK 32-bit (on x64 computer). The count won't go past 15. I have to use 32-bit AHK because of the way some of my scripts interact with 32-bit programs trough dll's.

One thing I noticed is Suspend On followed by Suspend Off (using the tray menu) is not working after hotkeys stop working. Looking at KeyHistory, the Keybd Hook is not released when hotkeys are suspended. I do not understand why because in the same script before the hotkeys stop working the Keybd Hook is always released with suspend.

EDIT3: The issue is that at some point with the 32-bit AHK on a 64bit OS, while counting to 50:
  • all conditional hotkeys stop working, while unconditional hotkeys keep working.
  • keybd hook gets stuk in the On state. Using the tray menu to suspend does not release it. With 64-bit ahk it can be released.
I'm looking for help with the following questions:
  1. EDIT2: Can you reproduce my issue with the script below with AHK 32-bit on an x64 computer? Can you make it count to 50?
  2. EDIT: Why is it working differently with AHK 32-bit and AHK 64-bit?
  3. Are there other script errors that could cause similar behavior as what happens with slow #If Expressions?
  4. What could I be looking for in my script to circumvent this when #IfTimeout 10 is not fixing it?
  5. Is there a way for the script to detect when Hotkeys are failing?
  6. Why is suspend not working to restore hotkeys and is there a way to force Keybd Hook to be released?
  7. Can I acces the information about Keybd Hook as shown in Keyhistory directly in the script?

Code: Select all

global cnt := 0

#If delay()
	Ctrl::FileAppend, Received %cnt%`n, *
#If
Alt::Fileappend, Still here %cnt%`n, *
Esc::Exitapp

delay()
{
	cnt++
	sleep, 400
	return true
}
Last edited by 2_05 on 18 Oct 2020, 05:41, edited 12 times in total.

User avatar
mikeyww
Posts: 26591
Joined: 09 Sep 2014, 18:38

Re: Hotkeys stop working after some time

Post by mikeyww » 16 Oct 2020, 16:43

I don't have all answers but maybe have a few. I cannot tell what you are trying to accomplish with the sleep. Can you explain it? When you press the key repeatedly during the sleep, that is perhaps the problem. If you actually want the Ctrl to trigger, then I'm not sure why you have the delay. Reading about Threads might be informative. I did not find Suspend in your script, so it's hard to comment on that. The script does not actually stop working; it's just that some of the key presses are not able to be "seen".

The following provides some idea of when the key is not seen.

Code: Select all

Global n := 0
Return

#If delay()
Ctrl::
SoundBeep, 1500, 20
Send %n% `
Return
#If

F4::ExitApp

delay() {
 n++
 Sleep, 400
 Return true
}
This variation may help you as well. It misses some keys but does not skip numbers. #MaxThreadsBuffer

Code: Select all

Global n := 0
Return

#MaxThreadsBuffer On
Ctrl::
delay()
SoundBeep, 1500, 20
Send %n% `
Return
#MaxThreadsBuffer Off

F4::ExitApp

delay() {
 n++
 Sleep, 400
 Return true
}

2_05
Posts: 31
Joined: 09 May 2018, 10:28

Re: Hotkeys stop working after some time

Post by 2_05 » 17 Oct 2020, 02:08

I did a test with a different computer and I can not reproduce it there. Looks like it is some problem with my laptop but what could it be?

On my laptop the hotkeys will stop working within 20 Ctrl presses. The presses can be 1s apart so missed presses is not an issue. After hotkeys stop working they stop working until I restart the script. Key presses are also not showing up on Keyhistory after that.

I tried using suspend hotkeys from the tray menu to try and unhook the keybd hook, but for some reason it will not unhook.

This script is just an example to reproduce an issue I'm having. The sleep is there to trigger a fault mechanism. It appears to cause faults on some computers but not on all.

User avatar
mikeyww
Posts: 26591
Joined: 09 Sep 2014, 18:38

Re: Hotkeys stop working after some time

Post by mikeyww » 17 Oct 2020, 07:29

Could be any of at least a few things.

1. Problem elsewhere within the script: this cause is frequent, at least on this forum. One common problem occurs when someone is testing and editing a script when other scripts are running at the same time (e.g., forgot to ExitApp from the last run). If you have more than one such AHK script running at once, it can cause lots of unexpected problems!

2. Bad memory or some sort of hardware issue like that-- but would be unusual and would also be extremely rare to affect more than one computer at the same time

3. Another program is interfering

These are big generic categories, of course-- but would look hard within the rest of your code.

2_05
Posts: 31
Joined: 09 May 2018, 10:28

Re: Hotkeys stop working after some time

Post by 2_05 » 17 Oct 2020, 09:26

Ran a few more tests.
Rebooted in safe mode: Problem still occurs
Full memory test: No issues found

Then did a reinstall of Autohotkey. Both my computers are x64
- AHK installed as 64-bit AHK. No issues with the script I posted above.
- AHK installed as 32-bit AHK. Issues on both my computers.

I'm forced to use 32-bit AHK since I have a script that is interacting with a 32-bit application through a dll, this only works with 32-bit AHK.

If you have an x64 system, can you give the script above a test with 32-bit AHK?

User avatar
mikeyww
Posts: 26591
Joined: 09 Sep 2014, 18:38

Re: Hotkeys stop working after some time

Post by mikeyww » 17 Oct 2020, 10:12

Done. No difference. Still skips as expected. This sort of skipping is documented in AHK.

It looks like you've done everything except look inside the rest of your code. I'm still not sure what you are trying to do with the script.

Edit: with further testing, I confirmed that 32-bit AHK ultimately fails to send (after about the first six successes), whereas 64-bit AHK succeeds. Not sure why.

Does anyone have an answer?

2_05
Posts: 31
Joined: 09 May 2018, 10:28

Re: Hotkeys stop working after some time

Post by 2_05 » 18 Oct 2020, 05:37

Thanks for confirming.

I know the script looks silly. I do not have a problem with missing hotkeys. I wrote it like this because I'm trying to understand why there is a difference with AHK 32-bit and AHK 64-bit.

The problem as you've also seen is that the script cannot count past 15 or so with AHK 32-bit. I wrote it like that because I found that this way the error can be reproduced consistently. Something similar happens in my real script, but it usually takes longer before it occurs and it is not consistent to reproduce. The conditional expressions in my real script are very short and take up 0ms when measured with tickcount and IfTimeout had no effect.

At some point with the 32-bit AHK:
  • all conditional hotkeys stop working, while unconditional hotkeys keep working.
  • keybd hook gets stuk in the On state. Using the tray menu to suspend does not release it. With 64-bit ahk it can be released.
I hope that if I can better understand the difference between 32-bit AHK and 64-bit AHK and understand why keybd hook gets stuck I can fix my real script.

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Hotkeys stop working after some time with 32-bit AHK on 64bit OS

Post by swagfag » 18 Oct 2020, 20:15

here are my(win10 x64 19041.572) observations based on the following(similar to OP's, OutputDebugStr since im launching from VS) script:

Code: Select all

global cnt := 0

#If delay()
	q::OutputDebug Received %cnt%`n
#If
*w::OutputDebug Still here %cnt%`n
Esc::Exitapp

delay() {
	cnt++
	sleep, 400
	return true
}
Ctrl replaced with q to see if keybd input gets through to a notepad window
Alt replaced with w for the same reason, and hardcoded(*) hook-enabled hotkey since standalone modifiers are always implemented with a hook

  1. run the script(from VS or otherwise)
  2. open up a notepad
  3. focus notepad's Edit1
  4. now observe both notepad and the debug console
  5. press q and wait
    • if u see q's print statement but a q doesnt appear in notepad: the hotkey was activated and correctly suppressed by ahk, that is to say, "the hotkey works". Goto step 6.
    • if u see q's print statement and a q appears in notepad: the processing of the WH_KEYBOARD_LL hookproc took longer than Windows permits(apparently governed by LowLevelHooksTimeout, although theres no such entry on my pc. more on that later), so Windows aborted any further processing of that proc and let the buffered input through. by contrast, AHK allows #If-expressions to evaluate for up to 1000ms(default), it eventually returns true, so the hotkey label is executed, thus printing to the debug log. Goto step 6.
    • if u dont see q's print statement and a q appears in notepad: the hook had already been long since disabled and u didnt follow closely the instructions in step 6. that told u to stop, dumdum!
    • if u dont see q's print statement but a q doesnt appear in notepad: logic dictates this cant happen
  6. press w and wait
    • if u see w's print statement but a w doesnt appear in notepad: the hotkey was activated and correctly suppressed by ahk, that is to say, "the hotkey works". Repeat from step 5.
    • if u see w's print statement and a w appears in notepad: if ure following the instructions stepwise, this cant happen
    • if u dont see w's print statement and a w appears in notepad: the WH_KEYBOARD_LL hook wasnt active when u pressed w. Windows must have disabled it by that point, because
      the docs copied some 10yo blog post wrote:On Windows 7 we have to make sure that the callback function of the hook can return in less than LowLevelHooksTimeout, which is 300 ms. And we allow for the application to be timed out 10 times when processing the hook callback message. If it times out an 11th time, Windows will unhook the application from the hook chain. This is a by design feature and it was added in Win7 RTM.
      Goto end, we're done here.
    • if u dont see q's print statement but a q doesnt appear in notepad: this cant happen

with ahk 1.1.33.02 U32(note that there was an update recently...ish to address probably similar hangup situations. see viewtopic.php?f=14&t=62932):
  • if sleep < 300ms: everything works, indefinitely, without breaking
  • if sleep ~ 300ms: occasionally a q will slip through, which means Windows aborted the hookproc's processing. after 11 q's have slipped through, Windows disables the hook altogether. Suspend/Unsuspend does nothing to reenable it.
  • if sleep > 350ms: every time u press q a q will slip through, which means Windows aborted the hookproc's processing. after 6 q's have slipped through, Windows disables the hook altogether. Suspend/Unsuspend does nothing to reenable it.
with ahk 1.1.33.02 U64:
  • if sleep < 300ms: everything works, indefinitely, without breaking
  • if sleep ~ 300ms: occasionally a q will slip through, which means Windows aborted the hookproc's processing. However, Windows never disables the hook
  • if sleep > 350ms: every time u press q a q will slip through, which means Windows aborted the hookproc's processing. However, Windows never disables the hook
  • if sleep > 1000ms(which requires raising AHK's default #IfTimeout):
    since a microsoft(?) guy wrote:There was an intentional change made here to limit the minimum value for a LowLevelHooksTimeout to 1 second starting in RS3 (RedStone 3) [ie 2017 Fall update]. The documentation has not yet been updated to reflect this change.
    every time u press q a q will slip through, which means Windows aborted the hookproc's processing. However, Windows never disables the hook

what can we glean from all this?
  • the latest version of x64 windows10(mine) kicks the hooks of 32bit applications that install them globally when they take around 300ms to complete after 11 timeouts.
    a stricter heuristic is employed if it takes them longer than that to complete(eg longer than 350ms -> kicked after 6 timeouts).
    it could be the case that the number of consecutive timeouts also contributes to the likelihood of the hook getting kicked, but that would take a microsoft employee to confirm
  • for 64bit applications that install global hooks, Windows will abort any further processing of the hookprocs after about 300ms but it wont kick the hooks themselves ever

why doesnt Suspend/Unsuspend(on 32bit) do anything after the hook has been kicked?
  • the hook handle is stored in the global variable g_KeybdHook
  • the HookThreadProc, which is launched from the main thread to run in a separate thread, idles in a blocking call to GetMessage() until a message is posted to its message queue from the main thread
  • the AddRemoveHooks() function is called in response to (among other things) Suspend/Unsuspend. it has a guard in the beginning. the way GetActiveHooks() determines whether hooks are active or not, is by checking whether the global variables contain any hook handles(ie whether they have nonzero values). however, even if they do have values, this doesnt mean that the hook handles are actually valid, as will become apparent soon enough.
  • to change a hook's state and signal to AHK that the hook is no longer active, ud have to zero the global variable. the only place where this is attempted is in the hook thread's message pump(HookThreadProc) and only after AHK has successfully managed to unhook the hook!
  • now suppose ur script is running, HookThreadProc idles on GetMessage(), g_KeybdHook has contains a handle. u intentionally cause a bunch of timeouts until Windows disables the hook(by what mechanism it does that is not clear but it probably calls UnhookWindowsHookEx() on the handle)
    • u Suspend(prompting a removal of hooks, aHooksToBeActive = 0)
    • a check is made to see if its necessary to actually do anything(it is, since GetActiveHooks() returned 1 because g_KeybdHook has a value)
    • the main thread posts a message to the hook thread telling it to unhook itself
    • the hook thread's GetMessage() unblocks and processes the message that tells it to unhook the keybdhook
    • the hook thread tries to unhook the keybdhook. However, it fails because Windows had already disabled the hook due to the timeouts, thus invalidating the hook handle that AHK had stored(last error 1404 ERROR_INVALID_HOOK_HANDLE, but this is not checked by AHK). now g_KeybdHook doesnt get reset. the hook thread goes back to idling on GetMessage()
    • u UnSuspend(prompting the installation of a keybdhook since u have hotkeys which require it, aHooksToBeActive = 1)
    • a check is made to see if its necessary to actually do anything(it is NOT, since GetActiveHooks() returned 1 because g_KeybdHook still contains an invalidated hook handle because it could never get reset). the function returns without having done anything, so no hooks get reenabled(AHK assumed they already were)

what can be done to fix this?
i dont know. handling ERROR_INVALID_HOOK_HANDLE when unhooking is probably a good start. or changing something else but there might be other hidden interactions between other components im not aware of, so i cant suggest anything meaningful. only @Lexikos can say
why do my hotkeys break when ive made sure their context-sensitive expressions finish fast?
other code might be preventing them from executing in a timely manner(eg calling into slow external code, slowmode PixelSearch, long running operations and blocking calls(files, network, etc)). consider this script

Code: Select all

global cnt := 0
PixelSearch, , , 0, 0, 40, 40, 123456
OutputDebug PixelSearch completed`n

#If delay()
	q::OutputDebug Received %cnt%`n
#If
*w::OutputDebug Still here %cnt%`n
Esc::Exitapp

delay() {
	cnt++
	; sleep, 400
	return true
}
here slowmode PixelSearch will do its thing for about 10sec(on my pc). if during those 10sec, u spam q enough times to trigger enough timeouts, Windows will still disable the hook, despite the fact that the #If-condition would have been evaluated almost instantly(under normal circumstances)
e 9.2.2023: fix github links
Last edited by swagfag on 09 Feb 2023, 02:40, edited 1 time in total.

User avatar
mikeyww
Posts: 26591
Joined: 09 Sep 2014, 18:38

Re: Hotkeys stop working after some time with 32-bit AHK on 64bit OS

Post by mikeyww » 18 Oct 2020, 21:06

I knew all of that but didn't want to make things so easy or straightforward. :lol:

Just kidding. That is all really very impressive. I get most of the idea, but I'm not so advanced. Hats off to @swagfag for these details!

2_05
Posts: 31
Joined: 09 May 2018, 10:28

Re: Hotkeys stop working after some time with 32-bit AHK on 64bit OS

Post by 2_05 » 19 Oct 2020, 06:26

Thank you for your comprehensive answer @swagfag. It provides a lot of clarity. Very informative to see what suspend is doing behind the scenes.

If I understand it correctly:
  • Windows 10 treats 32-bit applications differently than 64-bit applications when it comes to slow hotkey response. It is unclear why
  • Windows 10 kicks the keybd-hook for 32-bit applications when they are too slow. It does not kick keybd-hook for 64-bit applications
  • AHK is not notified of this
  • Suspend is not designed to handle loss of keybd-hook and therefore fails to reset the keybd-hook
  • Slow hotkey response can still occur if the #If expression is very basic, this can happen when the script is too busy to process the hotkey
  • Expiration of the hotkey response time can be prevented with the use of #IfTimeout
When keybd-hook is kicked:
  • Conditional (#IF) hotkeys stop working because they rely on keybd-hook
  • Hotkeys like *w:: stop working because they rely on keybd-hook
  • Hotkeys like Esc:: or w:: keep working because they don't rely on keybd-hook
  • A_TimeIdleKeyboard stops updating because it relies on keybd-hook
  • Keyhistory stops updating because it relies on keybd-hook
For some reason my script is not fixed with the addition of #IfTimeout. I'm starting some experiments now to see how slow Callback function's and slow OnMessage are handled. Are there other things that can cause windows to kick the keybd-hook?

I've experimented with ways to detect the loss of keybd-hook. E.g. having the script send hotkeys and check if they are received, but this causes more issues than it solves. Is there a more reliable way to determine if hotkeys are still working? A method that can be used by a timed thread?

2_05
Posts: 31
Joined: 09 May 2018, 10:28

Re: Hotkeys stop working after some time with 32-bit AHK on 64bit OS

Post by 2_05 » 20 Oct 2020, 12:00

I have identified why the hotkeys stop working despite the use of #IfTimeout (with AHK 32-bit).

I have found that some applications (not ahk script) on my computer can sporadically cause keyboard delay, even when these applications do not have focus. Even though the other application is responsible for the delay, it affects AHK. If other applications cause a key delay of over 300ms repeatedly, the AHK hook gets kicked. #IfTimeout does not stop this.

The following script is the desired script. There are no significant delays and it uses #IfTimeout to guard delays.

Code: Select all

; Myscript.ahk
#IfTimeout 100

;#IfWinActive, Not Existing Window ; Same problem
#If winex("Not Existing Window") ; Use this now so we can output messages
	*q::Return ; never reached, of course
#If
*w::Fileappend, Myscript still working`n, *
Esc::Exitapp

winex(win)
{
	we := WinExist(win)
	FileAppend, Myscript eval`n, *
	return we
}
To simulate third party applications that affect key response, I wrote the following script. This can represent any non-ahk application. In reality I have no control over the other applications on my computer, they are not AHK and I cannot alter them. I'm don't know when or why they delay key response.

Code: Select all

; Keydelayer.ahk: This script simulates a third party applications that slows keyresponse. In reality I have no control over this other application.
; IfTimeout not included on purpose. 

#If delay()
	q::return ; never reached, of course
	w::return ; never reached, of course
#If

delay()
{
	FileAppend, Keydelayer eval`n, *
	sleep, 500 ; Simulation of a badly programmed or hanging non-ahk application
	return false ; It just delays keys, it does not intercept them
}

Now I close all AHK scripts and do the following experiments with AHK 32-bit:
  1. Start keydelayer only. Hit q repeatedly: Output ("Keydelayer eval") stops after 6 presses (or less) of either q or w. The hook of Keydelayer has been kicked as expected.
  2. Close all. Start myscript only. Hit q repeatedly: Output ("Myscript eval") never stops.
  3. Close all (do not use reload). First start keydelayer, wait 10 seconds, then start myscript. Hit q repeatedly: Output("Keydelayer eval" and "Myscript eval") both appear for 6 presses of q (or less). After 6 presses all output stops. The hooks of both Keydelayer and myscript have been kicked. Myscript also stops functioning.
  4. Close all. First start myscript, wait 10 seconds, then start keydelayer. Hit q repeatedly: Output("Keydelayer eval" and "Myscript eval") both appear for 6 presses of q (or less). With the 6th hit, "Myscript eval" is shown twice?? After 6 presses the following presses only show output("Myscript eval"). The hook of Keydelayer has been kicked as expected. Myscript keeps functioning as expected.
  5. The above may not always be consistent. For more consistent results, compile keydelayer.ahk as 64-bit AHK. Then start keydelayer as 64-bit AHK, wait 10 seconds, then start myscript as 32-bit AHK. Hit q repeatedly. Output("Keydelayer eval" and "Myscript eval") both appear for around 6 presses. "Myscript eval" stops. "Keydelayer eval" keeps outputting.
Conclusion:
  • AHK 32-bit applications with conditional (#If) hotkeys are affected when other applications are slowing down keybd processing. The keybd hook breaks.
  • #IfTimout does not prevent this.
  • Once the keybd hook breaks, AHK is unable to recover from it without reload. Using suspend fails.
@swagfag Do you know why AHK keybd-hook breaks when other apps are slowing down keybd processing?

Is there any workaround for this?
@lexikos Is there a fix for this?

(I cannot change the third-party applications that may cause this and I cannot close them since I have to work with them. I'm using 32-bit AHK because I interact with 32-bit dll's, this does not work with the 64-bit ahk.)

User avatar
Guillaume
Posts: 20
Joined: 24 Nov 2017, 14:06

Re: Hotkeys stop working after some time with 32-bit AHK on 64bit OS

Post by Guillaume » 22 Oct 2021, 18:49

@2_05 You are my personal hero! Thank you so much for analyzing this issue, now I finally understand what was bugging my Redshift Tray all this time.

TheBeginner
Posts: 91
Joined: 19 Oct 2018, 12:05

Re: Hotkeys stop working after some time with 32-bit AHK on 64bit OS

Post by TheBeginner » 08 Feb 2023, 15:07

Hi @swagfag, do you know if this is still an issue or was it fixed somewhere along the way and the past three years?

User avatar
Guillaume
Posts: 20
Joined: 24 Nov 2017, 14:06

Re: Hotkeys stop working after some time with 32-bit AHK on 64bit OS

Post by Guillaume » 08 Feb 2023, 16:15

TheBeginner wrote:
08 Feb 2023, 15:07
Hi @swagfag, do you know if this is still an issue or was it fixed somewhere along the way and the past three years?
It was there at least until October 2021, haven't checked afterwards.

TheBeginner
Posts: 91
Joined: 19 Oct 2018, 12:05

Re: Hotkeys stop working after some time with 32-bit AHK on 64bit OS

Post by TheBeginner » 09 Feb 2023, 03:39

@swagfag
I wonder if it's still the case (don't have the environment to check it)
would you say that simply using the 64bit version mitigates the issue from your experience? (if it still exists)

I'm asking because I didn't completely understand the findings, and if there's anything to do about it

@Lexicos it will be an honor if you can share your thoughts about this, is this a thing still worth worrying about? is it something that's is relevant for v2 as well?

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Hotkeys stop working after some time with 32-bit AHK on 64bit OS

Post by swagfag » 09 Feb 2023, 04:51

havent tested it, but i doubt its fixed in either version, since nothings changed in the code relating to this. to be clear, this is only an issue affecting 32bit AHK on windows newer than 7
the not working Suspend/UnSuspend to reenable the hooks (after Windows has forcefully disabled them already due to them taking too long to execute, too many times) can be fixed in AHK if u add

Code: Select all

			else // Caller specified that the keyboard hook is to be deactivated (if it isn't already).
				if (g_KeybdHook)
					if (UnhookWindowsHookEx(g_KeybdHook) || GetLastError() == ERROR_INVALID_HOOK_HANDLE)
						g_KeybdHook = NULL;
here https://github.com/AutoHotkey/AutoHotkey/blob/27a2d5f2ae392c9d2cf2ef1a2f136659831749b8/source/hook.cpp#L4221-L4224 (and another similar one a bit further down for the mouse hook)
the fact that Windows disables "misbehaving" hooks in the first place cannot be fixed. that is a Windows "feature"

safetycar
Posts: 435
Joined: 12 Aug 2017, 04:27

Re: Hotkeys stop working after some time with 32-bit AHK on 64bit OS

Post by safetycar » 09 Feb 2023, 09:51

I seem to remember reading somewhere that #If calls should be designed to be fast. But I couldn't find where I took that from.
But trying to find that I saw this quote:
https://www.autohotkey.com/docs/v1/lib/_IfTimeout.htm wrote:Microsoft's documentation is unclear about the details of this timeout, but research indicates the following for Windows 7 and later: If LowLevelHooksTimeout is not defined, the default timeout is 300ms. The hook may time out up to 10 times, but is silently removed if it times out an 11th time.

Sparkon
Posts: 25
Joined: 04 Oct 2016, 15:55

Re: Hotkeys stop working after some time with 32-bit AHK on 64bit OS

Post by Sparkon » 08 May 2023, 23:15

I have been experiencing similar problems and came across this thread while Googling for a solution.

(By the way, for reference, I want to note that viewtopic.php?t=94066, an earlier thread which I came across while Googling, may or may not also be related.)

Anyway, just to report my experience:

For work, I have to keep something around 400 to 600 instances of a specific program open simultaneously throughout the entire day. I know that this is not an ideal situation, but I have no choice because this is a proprietary program, whose design I have no control over, necessary for my work. It's not as bad as it sounds because each instance uses only a small amount of memory and doesn't consume any CPU unless I'm actively working with a particular instance. Occasionally, I also have to run some CPU-intensive programs which will consume 100% of a specific core on the multicore system for a minute or so before completing its calculations.

I also have an AutoHotkey script permanently running with many hotkeys and hotstrings. (It is 32-bit AutoHotkey.)

Under these conditions, from time to time, the hotkeys and hotstrings will just occasionally/randomly stop working for no apparent reason until I reload the script, which, once or twice, is no big deal, but it gets pretty annoying when I have to do this every hour or so every single day.

Anybody have any ideas on how to mitigate this situation?

lexikos
Posts: 9553
Joined: 30 Sep 2013, 04:07
Contact:

Re: Hotkeys stop working after some time with 32-bit AHK on 64bit OS

Post by lexikos » 07 Jul 2023, 23:13

2_05 wrote:
20 Oct 2020, 12:00
I have found that some applications (not ahk script) on my computer can sporadically cause keyboard delay, even when these applications do not have focus. Even though the other application is responsible for the delay, it affects AHK. If other applications cause a key delay of over 300ms repeatedly, the AHK hook gets kicked. #IfTimeout does not stop this.
This is likely due to the way that the hooks work: the system calls one hook, then that hook decides whether or not to call the next hook. If it calls the next hook, that means it doesn't return until after the next hook returns. That in turn means that if a timeout occurs while any subsequent hook is executing, all previously called hooks still on the stack have also timed out.

One possible way around this would be to wrap the entire hook procedure in a timing check, and if the system timeout is exceeded, re-register the hook. However, there would be caveats:
  • The hook can't get an accurate measure of how much time is left if it wasn't the first hook called.
  • Re-registering the hook has side-effects, such as changing its priority relative to other hooks.
  • If we want to avoid re-registration when the hook hasn't been deactivated by the system, we would need to determine whether the hook is still valid without attempting to unregister it. I am not aware of any workable method aside from sending an event, which could be detected and blocked if the hook is still valid, but would otherwise pass through and may have side-effects.
Ultimately, it doesn't seem worth the risk given that 64-bit AutoHotkey doesn't appear to be subject to removal of the hook.

2_05
Posts: 31
Joined: 09 May 2018, 10:28

Re: Hotkeys stop working after some time with 32-bit AHK on 64bit OS

Post by 2_05 » 13 Jul 2023, 13:59

@Guillaume @TheBeginner Thank you for kicking this thread. It took me a lot of frustration and time to pinpoint the issue and to try and find a solution for it. I'm glad that my report about it was of help.
@lexikos Thank you for looking into it.

I noticed in the changelog that:
Changes & New Features wrote:Fixed an issue where any attempt to reinstall the keyboard or mouse hook would fail if the OS had automatically uninstalled the hook. It is still necessary to meet certain conditions before any such attempt can be made.
The same text is used in the changelog from AHK 1.1, but in the context of AHK 1.1 this doesn't seem to make any sense when it's described like this as AHK v1.1 does not have InstallKeybdHook as a command but only as a directive. So does this mean that it is now possible to use suspend to rehook the KeybdHook using suspend when the hook breaks in AHK v1.1?

Although 64-bit is now widely adopted, 32-bit can still be of need. When I encountered this issue I was working on a script that used of a dll to hook into a 32-bit application. It heavily relied on hotkeys and I encountered this issue almost hourly. As the application that it was build for was no longer of use to me I also stopped using this script. For the script that I'm currently working on, I'm using some libraries which use dll calls and I don't really know how to rewrite these for 64-bit. I have avoided the use of hotkeys for this recent script because of this issue.

lexikos wrote:If we want to avoid re-registration when the hook hasn't been deactivated by the system, we would need to determine whether the hook is still valid without attempting to unregister it. I am not aware of any workable method aside from sending an event, which could be detected and blocked if the hook is still valid, but would otherwise pass through and may have side-effects.
What if this was made behind a command, so that the user has control over whether or not to use this command in it's script?

I know it's a long shot, but is there a way to report this issue to Microsoft as a developer? I mean, I could report it but I'm missing the knowledge of how precisely hooks behave in Windows so I cannot describe the issue properly.

(I had already posted this as a new topic in Bug reports as well)

Post Reply

Return to “Bug Reports”