Say I have an autohotkey script C:\path\to\my\script running. Is there a way to define a hotkey that re-starts it?
In order to prevent duplicate instances, I normally do not re-launch a script but use the build-in function Reload. I launch this with Ctrl+Win+Alt+R and use Ctrl+Win+Alt+E to edit the main AHK script.
^#!r::Reload
Actually, my script looks like this:
^#!r::
Send, ^s ; To save a changed script
Sleep, 300 ; give it time to save the script
Reload
Return
^!#e::Edit
As a matter of fact, all the way at the top of my script I have this to give me a visual and audio indication that the script was restarted:
#SingleInstance Force
#installKeybdHook
#Persistent
Menu, Tray, Icon , Shell32.dll, 25, 1
TrayTip, AutoHotKey, Started, 1
SoundBeep, 300, 150
Return
Make a hotkey that runs a script, which in this case is the same script and then exit.
somehotkey::
Run, C:\path\to\my\script.ahk
ExitApp
return
I found this to be the safest option of them all, because it takes care that the correct script is reloaded when you have multiple scripts running simultaneously, which was a recurring issue for me. The combination of the following also ensures that only one instance of a script will ever run at a time. The ScriptFullPath variable includes the name of the script.
#SingleInstance Force ;put this at the top of the script
^r::run, %A_ScriptFullPath%
Related
I have written an AHK script that sends a set of keyboard keys when the hotkey ^!e:: is pressed. This script needs a couple of seconds to complete, but sometimes I need to stop the execution before the script has finished doing its task. I know that this can be done by setting the ExitApp function to another hotkey, but this will close the script. So, if I need to trigger the script again, it will be necessary to open the .ahk file anew.
How could the script be stopped without closing it? I would also need that, when it is triggered again, it sends the keys from the beginning, and not from where it left off when I stopped it.
Edit: let's take as an example this code,
^!q::
SoundBeep, 208
SoundBeep, 155
SoundBeep, 208
SoundBeep, 196
SoundBeep, 208
return
What you can do to resolve the issue is to have two different script-files.
MainScript.ahk:
; Starts the secondary-file into its own process:
^!l::run SecondaryScript.ahk ; Ctrl+Alt+L
SecondaryScript.ahk:
#SingleInstance Force
SoundBeep, 208
SoundBeep, 155
SoundBeep, 208
SoundBeep, 196
SoundBeep, 208
ExitApp
^!q::ExitApp ; Ctrl+Alt+Q
After the SecondaryScript has finished its auto-executing of code, then it will issue ExitApp which will kill the process that the file is currently being executed inside of.
If you want to abort the execution, then you can use the hotkey that is defined under the Auto-Execute portion of the script.
to do that:
1.go to the system tray ()
2.right-click on the symbol.
3.click on suspend hotkeys
What happens when you click on pause script? Something horrible.
ex:if you remapped the
key, that useful key will be shutdown.
hope this helped.
I found a trick to relaunch current script without a separate launcher script:
Esc::
Reload
ExitApp
Reload, obviously, reloads the current script.
(NOTE: Command-line parameters aren't passed down to the new instance.)
And then ExitApp makes sure current instance dies right away and even if the reload fails.
The effect is similar to the solution by Hampus, but doesn't require hardcoding or otherwise specifying any file names within the scripts, and is much more convenient for scripts with multiple long-running hotkeys, which would require a separate script file each with the launcher approach.
When testing AutoHotkey scripts, I sometimes forget to reload my scripts after making changes. This leads to me accidentally testing old, outdated versions of my scripts.
Instead of manually reloading the script, I would like to have scripts automatically reload if they have been modified.
How can I make AutoHotkey reload the current script any time a .ahk file is modified?
Somewhere near start of the script, in the auto-execute section
#SingleInstance force
FileGetTime ScriptStartModTime, %A_ScriptFullPath%
SetTimer CheckScriptUpdate, 100, 0x7FFFFFFF ; 100 ms, highest priority
Anywhere in the script (usually somewhere at the bottom):
CheckScriptUpdate() {
global ScriptStartModTime
FileGetTime curModTime, %A_ScriptFullPath%
If (curModTime == ScriptStartModTime)
return
SetTimer CheckScriptUpdate, Off
Loop
{
reload
Sleep 300 ; ms
MsgBox 0x2, %A_ScriptName%, Reload failed. ; 0x2 = Abort/Retry/Ignore
IfMsgBox Abort
ExitApp
IfMsgBox Ignore
break
} ; loops reload on "Retry"
}
This is how I've done it:
#If WinActive("AHK.ahk - Notepad") or WinActive("*AHK.ahk - Notepad")
~^s::
Reload
Return
#If
Checks if the current window is the script that I want autoreloaded whenever I hit Ctrl-S.
The ~ means the default action of Ctrl-S (saving the file) is preserved, and then we simply reload it.
I'm still new at AHK but here's what I've come with.
If you're using Notepad++ to edit AHKS this will run any ahk that's open and currently in focus in Notepad++ on saving with Ctrl-S and won't effect any other file types.
This script only has to be in one running ahk to work on all ahks being modified in Notepad++.
This can be used on multiple text editor programs too like win Notepad just get rid of the ++ associated with Notepad++
~^s:: ; Saves and Runs ANY AHK open in Notepad++
Sleep 150
WinGetTitle, Title, A
Needle := "ahk - Notepad++"
IfInString, Title, %Needle%
{
StringReplace, xxx, Title,- Notepad++, , All
run %xxx%
return
}
else
return
I have a shortcut to open the current running script in a text editor and then save it and close it. Upon closing, how do I update ahk to use the new updated settings?
This is what I have:
IfWinExist, test.ahk ahk_exe notepad.exe
{
WinActivate
Sleep, 100
Send, ^s
Sleep, 200
WinClose
}
else
MsgBox, window not found
app1Open=false
Reload
If you want to restart the script itself (that is, from its own process), use the Reload command.
Otherwise, if you want to restart the script from another process, you have to close it and then run the script again. In this case, you can either kill the script's process and run it again (not nice!). Or you can tell the script to gracefully Reload, for example in one of these two ways:
Inter-process communication: OnMessage() for the receiving process and PostMessage/SendMessage in the sending process
Defining a simple hotkey in your receiving script and sending that hotkey from another process
As MCL mentioned, use Reload. There is no need to close the script. Here is an example:
^!#r:: ; Save and Reload the script with Alt+Ctrl+Win+r
IfWinExist, SciTE4AutoHotKey
{
WinActivate
Sleep, 100
Send, ^s
Sleep, 300
}
Reload
Return
I have a very long script and I want to stop it with ESC key if it goes astray.
So I have put in the script this line:
Esc::ExitApp
But, of course, sometimes I have to press ESC key even when not running the script and when I need AutoHotkey, it's gone.
How do I tie ExitApp to ESC key just for a part of the script that's running?
You have to add ExitApp as a command in your script! It is a special kind of label, not a function. If the label doesn't exist in your script, you can't call it.
To make it exist, just add another line with the label on it. -->>**actually, I was wrong to say that. In the docs it gives the example that you can use simply Esc::ExitApp just like that to exit the running script ExitApp exists in the script even if you don't create it first because it's built into AutoHotkey. However, with your new code from your comment, you can use a custom label (which does have to exist in your script before you can call it):
Esc::goto DoSomething
DoSomething:
MsgBox, 4, , Are we exiting?
IfMsgBox, No
return ;after this return, the next line will not be called.
ExitApp ;as soon as this is called, the script ends completely and no more of the script will ever be called
return
this code is working:
Esc::goto ExitThisProgramQuestion
ExitThisProgramQuestion:
MsgBox, 4, , Are we exiting?
IfMsgBox, No
return
ExitApp
return
I'm testing AutoHotkeys as a way to block user's usage of Ctrl, Alt and Windows Key while an application is running. To do this, I compiled the code:
LAlt::return
RAlt::return
LControl::return
RControl::return
RWin::Return
LWin::Return
into an .exe using the compiler that comes with AutoHotkeys.
My problem is that normally when I close the .exe file (either by code using TerminateProcess(,) or manually) the keys are not released immediately. The Windows Key, for example, may take something like 10 seconds to be finely "unlocked" and become able to be used again, and for me this is unacceptable.
So I got two questions:
Is there a way to fix this problem? How can I make the keys to be released as soon as the .exe is closed?
Would there be any improvement if I tryed to get the same functionality by code? Or if I create the hooks by myself I would get the same problem I'm having with AutoHotkeys?
Thanks,
Momergil
AutoHotkey has a built-in command ExitApp for terminating your scripts.
This example makes Esc your termination hotkey:
Esc::ExitApp
It seems like the delay you are experiencing might be related to how long it's taking the process to close.
You could try making the hotkeys conditional with the #If command*
(i.e. they are only blocked when Flag = 1).
Then you can have the script quickly change the context just before ExitApp by using OnExit. The OnExit subroutine is called when the script exits by any means (except when it is killed by something like "End Task"). You can call a subroutine with a hotkey by using the GoSub command.
Flag := 1
OnExit, myExit
Esc::GoSub, myExit
#If Flag
LAlt::return
LCtrl::return
x::return
#If
myExit:
Flag := 0
Exitapp
* The #If command requires Autohotkey_L.
The other option that will be more verbose, but work for AHK basic, is the hotkey command.
Another option is to have AutoHotkey run the target application, and upon application exit, AutoHotkey exits as well. Here's an example with Notepad. When the user closes Notepad, the script gracefully exits.
RunWait, Notepad.exe
ExitApp ; Run after Notepad.exe closes
LAlt::return
RAlt::return
LControl::return
RControl::return
RWin::Return
LWin::Return
I would use winactive to disable these keys. In this example the modyfier keys are disabled for "Evernote". As soon as you switch to another program the keys are restored and when you switch back to Evernote the modifier keys are disabled again.
SetTitleMatchMode, 2 ; Find the string Evernote anywhere in the windows title
#ifWinActive Evernote
LAlt::return
RAlt::return
LControl::return
RControl::return
RWin::Return
LWin::Return
#ifWinActive