AutoHotkey: Could not close the previous instance of this script. Keep waiting? - autohotkey

I've got an AutoHotkey script that presents the following error when I try to run it again:
Could not close the previous instance of this script. Keep waiting?
It's a pretty simple script, with the following settings:
#NoEnv
#SingleInstance force
SendMode Input
DetectHiddenWindows, on
SetWinDelay, -1
I'm launching the script from the command line. I've tried using the /f / /force option and there is no effect.
I want the #SingleInstance Force behaviour described in the docs, which is described as:
Skips the dialog box and replaces the old instance automatically, which is similar in effect to the Reload command.

Turns out the problem was the SetWinDelay instruction.
From the docs:
Although a delay of -1 (no delay at all) is allowed, it is recommended that at least 0 be used, to increase confidence that the script will run correctly even when the CPU is under load.
A delay of 0 internally executes a Sleep(0), which yields the remainder of the script's timeslice to any other process that may need it. If there is none, Sleep(0) will not sleep at all.
When I had it set to -1 the script never had time to process other commands, including whatever exit command was sent to it.
Ensure SetWinDelay is greater than or equal to 0.

Related

How to get ExitApp to take effect immediately in AHK?

If I run the following code, if I hit the ^+q it does not stop entering the numbers 1-100. Only after it completes does the script exit. Is there a way to get the script to stop even if it is in the middle of sending keystrokes?
^j::
ArrayCount := 100
Loop % ArrayCount
{
Send, %A_index%
}
return
^+q::ExitApp ; Exit script with Escape key
There are 2 issues with your code.
Sendreleases modifier keys when it simulates input, using it in a loop this way is going to interfere with autohotkey's hotkey detection. You can still activate ^+q if you press the 3 buttons simultaneously but it's much easier to use a hotkey without modifiers for example the Escape key. This is also what your comment says you're doing
^+q::ExitApp ; Exit script with Escape key
so as a bonus it will fix the discrepancy between your comment and your code ;).
The second problem is that the loop in which you execute the Send command is going to finish very quickly if you use SendInput and by the time ExitApp is executed all the numbers were already sent(even if you don't yet see the effect). In case of SendEvent there is some other problem which prevents other threads from being executed when you do it in a loop(don't know what causes it, might be a bug).
To solve it you need to add Sleep. At my system doing Sleep 1 works well. You can experiment with different numbers and send modes until you get the desired effect(you can also try 0 and -1.
Full code:
^j::
ArrayCount := 100
Loop % ArrayCount
{
Send %A_index%
Sleep 1 ; experiment with how long to sleep
}
return
Escape::ExitApp ; Exit script with Escape key

MATLAB code break

I have started running a script on MATLAB that takes days to finish. Usually, if I changed my mind and I don't want wait for it to finish and I get content with the intermediate results, I highlight the command window and press Ctrl-C to break the code.
Now, I have run MATLAB. But its desktop got kinda stuck in the background. When I try to restore the desktop from the toolbar, it does not restore. But I know from the task manager that the process is running and is consuming Memory and CPU performance. So, I am kinda stuck. I don't want to kill the process because I need the intermediate values in the workspace, and I can't open the desktop to break the code using ctrl-c.
Is there any solution? For example, is there any command that can be used in the command prompt to act as ctrl-c for MATLAB?
I am using MATLAB R2012b and Windows 8.
Quick try to fix the recent Problem:
Try ty set a higher priority to matlab.exe in the Task Manager. (Right click -> Priority -> Higher than normal). Then see if you can get the window to front.
Some approaches to avoid this problem in future:
Try to optimize your code. For starters look at: http://de.mathworks.com/help/matlab/matlab_prog/vectorization.html
Use Matlab compiler for faster execution: http://de.mathworks.com/products/compiler/
Include some drawnow commands at stratetic positions in the code. This allows matlab to process the Event Queue and capture ctr-C commands.
Save intermediate results to output files. For example you could write an output file all 30 min with your intermediate results. Easyiest way would be just save(filename). Then a .matfile with all your workspace variables is generated. You can than kill the process in the task manager, without loosing too much results.

Hotkey to restart autohotkey script?

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%

How can I make AutoHotkeys's functions stop working as soon as the .exe is closed?

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

Stop a script in Matlab

My question is, how do I stop a script by a pressing a GUI button? I already tried to write a code that simulates "CTRL+C" press, but it doesn't work.
I'm not sure there's a way to stop another script from being called. One alternative would be to set a global variable that's periodically checked by the script you wish to stop. If you set the value of a "stop processing" variable to true in your callback, the other script could stop if it found that it was supposed to stop.
Edit
If you'd like to have a GUI option to stop an ongoing process, I would recommend you take a look at something like STOPLOOP on the MATLAB File Exchange.
I won't write the code for you but here's a high-level way to accomplish this:
Display a waitbar with a button on it. Create a callback function for the button which sets a flag to true.
Begin computation inside of a for-loop. In the loop:
1. update the waitbar.
2. call the drawnow function so that the callback is executed properly. Remember MATLAB is single-threaded, so this is necessary or the callback will not execute until the script finishes.
3. perform any other computation
4. check for the flag set to true. if it is true, return to stop execution.
The flag could be a global variable, or a handle-based object (so that it is passed by reference).
EDIT:
This answer is not applicable for the current question.
This answer is applicable only for scripts having the first line = #!/usr/bin/matlab
use pkill without option will send a TERM signal:
pkill yourscriptname
If you really want the same signal as CTRL+C then:
pkill -3 yourscriptname
If your script still does not stop, you can use the most aggressive signal KILL:
pkill -9 yourscriptname
Of course, if you known the PID (Process IDentifier), you can simply use kill:
kill yourPID
kill -3 yourPID
kill -9 yourPID
You can have more info about signals using one of these commands:
man 7 signal
kill -l
info signal
I don't do a lot of GUIs, but for debugging purposes I would try to set the button callback to #keyboard. That is, something like:
set(handleToGuiButton,'Callback',#keyboard)
To actually stop execution you would need to somehow communicate this button press into the loop that was executing, for example via global variables, or something fancier (e.g. https://stackoverflow.com/a/8537460/931379)
But I would honestly look at the stoploop link (from another answer) before going down any of these routes.