Why does script stop working and need to be reloaded? - autohotkey

I have a script that I use to open Firefox that contains customized shortcuts and that closes when I close the browser. Lately when I first open it and try to use a shortcut, it does not work until I reload the script, even though the script is still running. I haven't changed anything in the script in a while. Can anyone tell me what's going on?
Thanks,
Ellen
Menu, Tray, Icon, C:\Program Files\Mozilla Firefox\firefox.exe
SetTitleMatchMode, 2
runwait C:\Program Files\Mozilla Firefox\firefox.exe, , max
IfWinExist ahk_class MozillaWindowClass
Return
ExitApp
Return
#SingleInstance Force
#installKeybdHook
#Persistent
Return
#ifWinActive Mozilla Firefox
^!b::send, ^+b
^b::send, ^d ; bookmark page]
^n::send, ^t ; open new tab
!c::send, ^w ; close current tab
^d::send, ^!t ; duplicate tab
^u::send, ^+t ; undo close tab
!d::send, ^j ; open downloads
^e::
MouseClick, left, 33, 44
Sleep, 100
MouseClick, left, 33, 230
Sleep, 100
return
^r:: ; recent pages
MouseClick, left, 79, 76
return
!a:: ; click on address bar
MouseClick, left, 368, 73
return
^q:: ; roboform
MouseClick, left, 864, 722
return
^BS::send, +{Backspace} ; forward
Up::send, ^{+} ;zoom in
Down::send, ^{-} ;zoom in
::abc::about:config
#ifWinActive

To me the problem with your script seems to be that the runwait makes the script stop the the current thread that is running firefox.
That thread then waits for firefox to close giving you the "STILL WAITING"... then when it closes the next line is IfWinExist ahk_class MozillaWindowClass and it will not exist making the script skip to Exitapp
While RunWait is in a waiting state, new threads can be launched via hotkey, custom menu item, or timer.
When using RunWait some programs will appear to return immediately even though they are still running, these programs spawn another process. With the way your script is setup it may stop RunWait from going into this waiting state once in a while.
And this will make you unable to launch new threads as autohotkey is not multi threaded...
So I say use something like WinWaitClose as that will also let you launch new threads
While WinWaitClose is in a waiting state, new threads can be launched via hotkey, custom menu item, or timer.
Something like this:
Run, C:\Program Files\Mozilla Firefox\firefox.exe, , max
WinWait, ahk_class MozillaWindowClass
WinWaitClose ; Wait for the exact window found by WinWait to be closed.
Exitapp
Hope it helps

Related

autohotkey how to activate last opened window that changes its pid

I'm trying to setup a hotkey to always launch a new WindowsTerminal window and give it focus. Even if there is an existing window, I always want it to create a new window. I'm able to get the new window to run, but I'm having difficulty making it the Active window.
Capturing the pid during the Run command and using ahk_pid doesn't seem to work as the pid changes between launch and the active window that appears (msgbox debugging shows one pid, Window Spy shows a different pid). Using WinWait, ahk_exe WindowsTerminal.exe seems to return right away grabbing a pre-existing window.
#t::
Run, wt.exe, , , TermPid
;; TermPid seems to change between the launch and the final window that appears
WinWait, ahk_pid %TermPid%, , 3
if ErrorLevel {
MsgBox, WinWait timed out... %TermPid%
return
} else {
WinActivate
}
;; problems when there are other already existing WindowsTerminal.exe windows
;WinWait, ahk_exe WindowsTerminal.exe, , 3
;if ErrorLevel {
; MsgBox, WinWait timed out...
; return
;} else {
; WinActivate
;}
return
I tried to create before and after array containing the PIDs to determine which process was the newly created one, but targeting the last PID in the array created below seems to work as is.
Code:
#t::
Run, wt.exe
;If you are on a slow computer, you may need to increase this delay
Sleep 100 ;Forgot how to optimize this w/ WinWait, but not important rn bc its not critical
newArray:=[]
for proc in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process"){
if(proc.Name=="WindowsTerminal.exe"){
prID := proc.ProcessId
newArray.Push(prID)
}
}
LastItem:=newArray[newArray.MaxIndex()]
WinActivate, ahk_pid %LastItem%
return

Lost focus in browser when using clipboard for search query [autohotkey]

I am using a simple script to run a google/wikipedia/etc search using a hotkey, unfortunately after the search result appears in a new tab, I have to click because the tab is not on focus, although the browser windows is on focus. I tried to add a WinActivate but it's not working. This script used to work as expected before a new OS installation. Why is this script making lose focus on the browser?
Here's the script
^+g::
{
Send, ^c
sleep 200
Run, https://www.google.com/search?hl=en&q=%Clipboard%
sleep 50
WinActivate, ahk_exe waterfox.exe
}
Return
I don't know why, but it looks like increasing the delay between the Run and the WinActivate seems to fix it.
^+g::
{
Send, ^c
sleep 200
Run, https://www.google.com/search?hl=en&q=%Clipboard%
sleep 500 ;Up from 50, you might be able to fine-tune this number based on your computer's speed
WinActivate, ahk_exe waterfox.exe
}

Auto Maximize skype live conversation window with Autohotkey

Here is what I'm trying to do and would greatly appreciate any help here.
I am trying to automate maximizing the live conversation window in skype with an Autohotkey script. I'm trying to make it so I can call into a remote machine using skype and have it auto answer (this is native in skype)...once I have a live conversation window I would like to maximize the live conversation window to fill the screen.
I've given this a shot but somehow don't think that I have the correct ahk_class for the live conversation window but there may be something else I am missing. I've placed a the code I've tried using below...any help would be great.
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
#Persistent
IfWinExist, TLiveConversationWindow ;
{
WinActivate
WinMaximize
send !{Enter};When using skype normally this Alt+Enter will maximize the window
return
}
I also tried to use this code to determine the proper class for the live conversation window...but has not helped as of yet.
Alt & Enter::
IfWinExist, TLiveConversationWindow
WinActivate
ControlFocus, ClassNN TLiveConversation1
ControlClick, ClassNN TLiveConversation1, , , , 2,
MouseClick, left, , , 2
send !{Enter}
; now we get the ID & CLASS
WinGet, Active_Window_ID, ID, A
WinGetClass, Active_Window_Class, A
MsgBox, The active window's class is "%Active_Window_class%" and ID is %Active_Window_ID%
Was able to get a simplified version of the code to work with a hotkey to initiate but have not been able to get the WinWait function to work as per #Schneyer.
Functioning Code activated by hotkey
#NoEnv
#Warn
#Persistent
SendMode Input
SetWorkingDir %A_ScriptDir%
; Skype Maximizer initiating functions
^!p::
;WinWait ahk_class TLiveConversation1
;WinWait ahk_class TConversationForm
;WinWait ahk_class TLiveConversationWindow
;WinMaximize ahk_class TLiveConversation1
;functioning code
;Activate tSkMainForm.
WinActivate ahk_class tSkMainForm
;Send Alt Enter Input to maximize.
SendInput !{Enter}
;TLiveConversationWindow Always On Top
WinSet, AlwaysOnTop,,ahk_class TLiveConversationWindow
;Minimize main form
WinMinimize ahk_class tSkMainForm
Return
When swapping the ^!p:: with any of the WinWait Functions nothing seems to happen. The WinWait seems like it should be the proper method, any thoughts on why it won't work?
Problems
#persistent lets the script run, but your code still gets executed only once when you start the script. After that it stays active but does nothing.
Use a WinWait to wait for the window to appear (wrap it in a Loop if you want it to run more than once).
Use ahk_class to to search for a window class instead of the window title
Working code
You can use the Window Spy tool which is included in AHK. Use the tray icon menu of a running AHK script to start it.
I use TConversationForm in the code, but it works with every window class.
#NoEnv
#Warn
SendMode Input
SetWorkingDir %A_ScriptDir%
WinWait ahk_class TConversationForm
WinActivate
WinMaximize
Scanning through AHK forums I was able to find a post that led me to the answer for this little problem. Check the below link for further information.
https://autohotkey.com/board/topic/96491-detect-when-a-classnn-window-exists/
The problem with using ahk_class to identify when a skype call was active is that the "active call window" identified as classNN TLiveConversation1 in the inspector was actually a Control within the window of ahk_class tSkMainForm rather than a Window. This made the WinWait function ineffective at identifying it when the call initiated.
In order to identify the Control it is necessary to loop through the controls (using WinGet) in ahk_class tSkMainForm until the TLiveConversation exists and then kick off any subroutines needed. For me that was to maximize the live conversation window.
You'll see the code to do this starting with the WinGet function. All of this is wrapped in a while loop so that it will run persistently allowing it to be called over and over. In essence this code will do the following:
Create a list (SkypeControlList) of controls existing in ahk_class tSkMainForm.
Continually Loop Through SkypeControlList
When a new Live Conversation is initiated a control TLiveConversation1 will exist
Once TLiveConversation1 esists run necessary code
#NoEnv
#Warn
#Persistent
SendMode Event
SetWorkingDir %A_ScriptDir%
DetectHiddenWindows, on
stop = 0
Loop
{
While stop = 0
{
WinGet, SkypeControlList, ControlList, ahk_class tSkMainForm
Loop, Parse,SkypeControlList, `n
{
;Loop to search for control TLiveConversation1
if (A_LoopField = "TLiveConversation1")
{
;Deactivate active screensaver
PostMessage, 0x0112, 0x0F060, 0,, A
;RegWrite REG_SZ, HKEY_CURRENT_USER, Control Panel\Desktop, ScreenSaveActive, 0
;SetKeyDelay, 500
Send {Esc}
;Activate tSkMainForm.
WinActivate ahk_class tSkMainForm
;Send Alt Enter Input to maximize.
Send !{Enter}
;TLiveConversationWindow Always On Top
WinSet, AlwaysOnTop,,ahk_class TLiveConversationWindow
stop = 1
sleep, 100
}
}
}
IfWinExist ahk_class TLiveConversationWindow
{
stop = 1
sleep, 1000
}
IfWinNotExist ahk_class TLiveConversationWindow
{
;Minimize all windows by win+D show desktop
send #d
sleep,1000
; is that call quality feedback window up? kill it.
SetTitleMatchMode, Regex
WinClose, ^Skype.*Call quality feedback$
stop = 0
}
sleep 1000
}
Return
The above code works great as long as there is no screen saver active on the machine being called. If there is an active screen saver the call will answer but the screen saver will not go away. You can see remnants of code trying to wake the computer from a screen saver (This does not currently work).
I've also added a few bits of code to clean up the experience such as removing the call quality popup window that skype throws up after a call as well as clearing the desktop after the call ends.
Thanks to #Blauhirn and #Schneyer for their input in trying to get this solved.

Writing a Simple AutoHotkey Script (press a key every X second on desktop)

I need to press any useless key (like F11) every 5 minutes or less to keep the windows active (if it became inactive for 10 minutes it will lock-out).
But I need the key to be pressed on the desktop (so it doesn't effect any open windows).
I have tried
Loop
{
ControlSend, {F11}, WindowsApplication1
Sleep, 100000
}
but doesn't seem to work.
thanks.
edit: my current script:
#NoTrayIcon
NumLock::Run Calc.exe
PrintScreen::Run "C:\Windows\Sysnative\SnippingTool.exe"
; When I press Insert, I want to Show Desktop
Insert::Run, "%A_APPDATA%\Microsoft\Internet Explorer\Quick Launch\Shows Desktop.lnk"
; When I press Pause/ Break, I want to Lock the Computer
Pause::DllCall("LockWorkStation")
#IfWinActive, ahk_class CabinetWClass
~MButton::Send !{Up}
#IfWinActive
Return
Just move the cursor every X minutes:
#Persistent
SetTimer, MoveMouse
MoveMouse:
If ( A_TimeIdle > 300000 ) {
MouseMove, 1 , 1,, R
MouseMove, -1,-1,, R
}
Return
Code adopted from here.
This is definitely nothing that should require Autohotkey.
Just disable your screensaver.
Rightclick your desktop
Click Personalize (Vista/7/8) or Properties (XP)
Go to the screensaver options
Disable the screensaver
You might also wanna disable stuff like "turn off display after x minutes", "go to sleep after x minutes" and "turn of harddrives after x minutes".
You'll find that in the poweroptions. There is a button in the screensaver options to get there...
edit: Another way of disabling the screensaver using autohotkey would be the following script:
#Persistent
Menu, Tray, Icon, User32.dll, 4
Menu, Tray, Tip, Screen Saver Disabled !!!
OnExit, ScreenSaveActivate
DllCall("SystemParametersInfo", Int,17, Int,0, UInt,NULL, Int,2)
SetTimer, CheckScreenSaveActive, 999
Return
CheckScreenSaveActive:
DllCall("SystemParametersInfo", Int,16, UInt,NULL, "UInt *",SSACTIVE, Int,0)
If SSACTIVE
DllCall("SystemParametersInfo", Int,17, Int,0, UInt,NULL, Int,2)
Return
ScreenSaveActivate:
DllCall("SystemParametersInfo", Int,17, Int,1, UInt,NULL, Int,2)
ExitApp
Return
which was created by SKAN from the ahk forums.

Timer runs only once

Below script works fine.
It sends mouse clicks every 4 seconds
to KingSoft Writer.
But when I change the Timer length to -4000
instead of 4000 so that the timer will run only once
the script no longer works even once.
I am no longer able to send mouse clicks to
KingSoft Writer.
What am I doing wrong?
#Persistent
#SingleInstance
SetTimer, CheckApp, 4000
Return
CheckApp:
IfWinActive, ahk_class QWidget
{
sleep 2000
Click 486, 15
Click 570, 93
}
Return
Before I answer this question. Would you be so kind as to go back to the previous question and mark the answer you received there, by clicking on the WHITE check-mark to turn it GREEN.
I once tried the minus values and was not happy with the results, so I decided to always turn the timer off instead of using negative values.
#Persistent
#SingleInstance
SetTimer, CheckApp, 4000
Return
CheckApp:
IfWinActive, ahk_class QWidget
{
SetTimer, CheckApp, Off
Click 486, 15
Click 570, 93
}
Return
I removed your Sleep, 2000. Adding this sleep command blocks ahk 50% of the time (sleeping 50%) and adds nothing useful. It even makes the chance that another application steals the focus in those 2 seconds larger, so the mouse clicks could go to another application...
Do you have to use mouse clicks or can you use keyboard shortcuts. Mouse positions tend to be unreliable as menus move or expand/contract.
Update
#Persistent
#SingleInstance
Return ; Prevent the [Win]+w from executing on startup of script.
#w:: ; [Win]+w launches PolyEdit, waits for window and sends two mouse clicks.
Run, path to the PolyEdit window.exe
WinWaitActive, ahk_class QWidget
Sleep, 1000
Click 486, 15
Click 570, 93
Return
Now you can put the ahk script in the windows start menu and launch PolyEdit through [Win]+w (or any other key you define...)
Update 2
Not sure why you want to do this, because launching the app takes an action (clicking an icon or pressing a shortcut), which could be used to trigger the script. Now you have to constantly run checks in the background. You can create an icon that looks like KingSoft, but in reality is an ahk script.
But here you go!
#Persistent
#SingleInstance
SetTimer, CheckApp, 400
Return
InitiateKS := true
CheckApp:
IfWinExist, ahk_class QWidget
{
If InitiateKS
{
InitiateKS := false
WinActivate, ahk_class QWidget
TrayTip, KingSoft, Started, 1
;Click 486, 15
;Click 570, 93
}
}
Else ; if no KingSoft is running
{
InitiateKS := true
}
Return