MaxLauncher- How to Close programs

I was really exited when I found this program launcher as it has the same interface as my Stream Deck. So COOL!!!

But, with stream deck I can close programs as well with hotkeys assigned to a button. That is great as I don’t have to remember the hotkey, all I have to do is hit the button.

Hotkeys to PC

If you are on desktop or in any program you can invoke a AutoHotKey script with a hotkey.

So I thought if I could programmatically send a hotkey by calling a hotkey from a MaxLauncher(ML) button then I could make a hotkey that would target an ExitApp of a script I had running. So the ML button would point to a script that only had say send, ^3 and that Ctrl+3 hotkey would work.

Not so simple it seems.

The area of particular interest to me is in the Browser. On my Stream Deck I have a Close Tab button that I use all the time, its really handy as you don’t have to go to the tab and click on the x to close it, but only have the tab active, then hit the button, the key is Ctrl+W, a Firefox Shortcut key.

So my main focus was on getting this to work as its such a handy button. Yes, you could just remember Ctrl+W but I have found the button so handy as its next to all the common web pages I use, so in the middle of the day I’d check Tides & weather just when I was thinking of taking the dog for a walk and its easier just to hit the close tab on the fly without using the mouse.

So the focus was on assigning a hotkey to a ML button.

ML target argument

I had tried adding an argument to the Target program, so target AHK Command Picker and then using the close hotkey for that program, it seemed to work first time but subsequently would not, and if it did then it was erratic.

Also that wouldn’t work for the browser.

AutoHotKey 1st attempt

So, first I tried AutoHotKey to write send ^3 in a AutoHotKey script assigned to a key, that didn’t work. I tried the SendRaw, SendInput and all the other variations of this method that were on the send page.

Bat & vba

Then .Bat file but that goes into a control console, so that didn’t work

next with .vba script called by .bat and that didn’t work either

Python

next with python script, after loading latest version (3.9) and using “keyboard” and “pyautogui” libraries, that didn’t work either

All of them seemed to work initially then they didn’t, I’m wondering if there is a buffer that gets filled and then doesn’t flush? Not sure as it works all the time on the stream deck.

Fun to be playing with Python again. I suppose its like AHK, the script will run if you have python running in the background as AHK scripts have AutoHotKey.exe running in the background.

That was what put me off python before, you couldn’t make a stand alone .exe file to pass around (actually you can, but when I tried it it wasn’t amazingly successful).

import pyautogui

pyautogui.hotkey('ctrl', 'w')
quit()

#or with keyboard library
import keyboard
keyboard.send('ctrl+w')
exit

#Neither work consistently

PowerShell to Computer HotKeys

I also got some PowerShell scripts to work a couple of times, then they stopped working. I suppose a bit liker .BAT being the old Dos format (that’s what I played with years ago, pre windows). I just found some of these this morning. A bit like Python & AutoHotKey. They start to work and then stop working.

Interestingly, these worked in the basic computer, so I’d have an script open and its close hotkey is Alt8 and it worked. I started a script and closed it by calling the PowerShell script. But it didn’t seem to work with Ctrl+W for tabs in firefox browser. I even found a script for running in a browser (https://sumtips.com/software/browsers/automatically-cycle-through-tabs-in-any-browser/) but replacing firefox for opera and the sendkey didn’t seem to work.

There is no “win key”, just shift + escape, which does the same thing.

SendKeys.Send("^{ESC}")

Another issue is I can get script running in VS Code but not as a run on the file, apparently this is to do with permissions of PowerShell. To resove this you have to start PowerShell in admin mode and choose one of the following after typing in PowerShell > Set-ExecutionPolicy

Set-ExecutionPolicy : Cannot bind parameter ‘ExecutionPolicy’. Cannot convert value “” to type
“Microsoft.PowerShell.ExecutionPolicy”. Error: “The identifier name cannot be processed because it is either too
similar or identical to the following enumerator names: Unrestricted, RemoteSigned, AllSigned, Restricted, Default,
Bypass, Undefined.
Use a more specific identifier name.”

In looking at Powershell>Get-Process

You see that all the AutoHotKey scripts are listed as AutoHotKey with different PID’s that you need to target (see below) so for testing use an .EXE file as it comes up with its individual name. I was testing this with TimeCapture++.exe for closing the program with Alt+8 script hotkey and it worked fine and consistently.

In In looking at Powershell>Get-Process AutoHotKey scripts are unidentified, even if you go into Task Manager and look at the details tab it only shows you that there are a number of instances of AutoHotKey running and it doesn’t tell you which is which, although they do have different ID’s.

In AutoHotKey there is WinGet that will tell you the tiltle of each instance and its PID , but that is only in AutoHotKey.

So from PowerShell point of view, it doesn’t work with AutoHotKey unless the scripts are complied into .EXE files, then you can target with Powershell>Get-Process

End result of 3 days effort

Although I was persistent, I didn’t seem to get much closer to getting this to work, the hotkeys all ended up in the ether, they may work one or 2 times and then they wouldn’t.

All of the above programs are pretty powerful and should be able to do something with sending keys to the computer, but all didn’t. I have yet to figure out why that is.

It was bugging me that I couldn’t get this working

Targeting the program and then sending input to the program- Finally Close Tab works

After thinking about it a bit more, I decided that I needed to focus on having the program activated prior to running the hotkey. I found this article on Reddit (https://www.reddit.com/r/AutoHotkey/comments/eo43tr/sending_keys_to_firefox_not_having_any_effect/) that pointed the way forward.

First you need to activate the program window then use ControlSend instead of send and it works. So I wrote a script that does that and Hurray Hurray I can close tabs with MaxLauncher.

; https://www.reddit.com/r/AutoHotkey/comments/eo43tr/sending_keys_to_firefox_not_having_any_effect/

WinActivate   , Mozilla Firefox						;activate FF    

SetKeyDelay, 10, 10   ; this seems improtant so typing not too fast
ControlSend, ahk_parent, ^w	, ahk_class MozillaWindowClass    ;close tab

send, ^W

Stop Scripts for restart after edit

I’m editing scripts, mainly tweeking them, and I can do this by opening Notepad++ and having the argument as the file I want to edit. I can set this up for autocorrect, CommandPcker & EmailTap scripts. After editing I want to reload the scripts so that I can use the updated version.

I found there was a method using AutoHotKey process but that only allowed you to close the program, not restart it, but that said, having a start script button is no issue as I’ve lots of keys on MaxLauncher at the moment, so I can assign a key to start the program too. Maybe later I can just include a restart in a bat file so that you can chose to close or close then start the program (maybe worth exploring later) so that you can fit it onto one button.

An Aside- AutoCorrect has a hotkey for adding a new single text expander line Win5 or CtrlShift5

I’ve since found out that AutoCorrect has a hotkey for adding a new single text expander line and it restarts script automatically. So not so much use for the Editing in Notepad++ as its so much easier, I just need to make a key so I don’t have to remember it, also I think it works if you select a bit of text first.

Get PID of script to then action

Finding an active Script to then stop was a bit of a challenge. The reason being each time the script is started it has a new ProcessID (PID) so you have to find its number so you can action it. Also if you have a couple of instances open (in AutoHotKey scripts you can put #SingleInstance to stop this from happening) but for programs like file Explorer you can have multiple instances each with a different window id, but all having the same Process ID.

Anyway, to target the scripts, which are running in the background, so do not have an active window you need to loop through all of the AutoHotKey open scripts to find its individual PID, and once you have this you can then close that process. The script is below ONLY STOPS A SCRIPT

DetectHiddenWindows, ON
SetTitleMatchMode, 2

;find the script that you want to close
ProcName = AHKCommandPicker.ahk  ;EmailDateMultiTap.ahk   ;AutoCorrect.ahk ;TimeCapture++.exe

;get the id of the script
WinGet, id, List, %ProcName% 

;find the PID of the script (this is the new active process)
; each time a new instance is started it has  a different PID
Loop, %id%
{
    this_id := id%A_Index%
    WinActivate, ahk_id %this_id%
    WinGet, PID, PID, ahk_id %this_id%    
}

;Use the PID as the ID of the instance  and close it
  Process, Close,  %PID%
 
exitapp

Enlarging on the above, we can use the PID to activate the identified window and then can just use send, #!XYZ to that program , thereby triggering the hotkeys in that script, thusly:

DetectHiddenWindows, ON
;SetTitleMatchMode, 2

;find the script that you want to close
ProcName = AutoCorrect.ahk ;TimeCapture++.exe; AHKCommandPicker.ahk  ;EmailDateMultiTap.ahk   ;

;get the id of the script
WinGet, id, List, %ProcName% 

;find the PID of the script (this is the new active process)
; each time a new instance is started it has  a different PID
Loop, %id%
{
    this_id := id%A_Index%
    WinActivate, ahk_id %this_id%
    WinGet, PID, PID, ahk_id %this_id%    
}

WinActivate, ahk_id %PID%
;Use the PID as the ID of the instance  and close it
Send,  ^!5	

The above script gets a Hidden Window and uses WinActivate, ahk_id %PID% so its looking for ahk_id instead of the usual ahk_class which I would normally use.

So after messing around with PowerShell most of the day AutoHotKey has been the main solution for all the actions I want so far.

Lessons learned (painfully)

  1. Focus on an active window of a program before sending hotkeys. Sending them into the ether doesn’t seem to work
  2. For AutoHotKey scripts, which are all bundled together, you need to find the PID (Process ID) (https://documentation.help/AutoHotkey-GUI/WinTitle.htm#ahk_id) and then use that to active the window, especially if it’s a hidden script sitting in your Task Bar Tray.
  3. After going around the houses with Bat, VBA, python & PowerShell, AutoHotKey seems to be able to meet all my needs
  4. I do not need to break all the scripts down into individual functions but can keep the running script and make Hotkey calls to that. Far tidier.

End comment

This has been a painful journey and not that much learning along the way. I’m glad I have the basic function buttons for Firefox tab manipulation up and running and also AutoHotKey scripts controllable using Hotkey calls to running scripts. That simplifies using my existing code.

Now I have the main rudementary buttons that I use most of the time on my Stream Deck I can now start looking at other keys that I use on that too. Another post for that.