bash AutoHotKey

Eine Funktion zur Ausführung von AutoHotKey von der Linux-Befehlszeile implementieren

Ich habe eine Funktion implementiert, um AutoHotKey von der Linux-Befehlszeile aus auszuführen, also werde ich sie vorstellen. Ich habe eine Implementierung erstellt, die flexibles Codieren mit Argumenten von WSL Bash zu autohotkey ermöglicht. Da autohotkey keine stdout (Standardausgabe) in dem hat, was allgemein als Shell bezeichnet wird, können Sie im Gegensatz zu Python oder Ruby keine Werte von Bash-Skripten an autohotkey übergeben und verarbeitete Werte als Standardausgabe empfangen...

Shou Arisaka
7 Min. Lesezeit
30. Okt. 2025

<> Ich habe eine Funktion implementiert, um AutoHotKey von der Linux-Befehlszeile aus auszuführen, also werde ich sie vorstellen. Dies ist eine Implementierung, die flexibles Codieren mit Argumenten von WSL Bash zu autohotkey ermöglicht.

Da autohotkey keine stdout (Standardausgabe) in dem hat, was allgemein als Shell bezeichnet wird, können Sie im Gegensatz zu Python oder Ruby keine Werte von Bash-Skripten an autohotkey übergeben, verarbeitete Werte als Standardausgabe empfangen und sie pipen… </>

Image

OutputDebug

Es gibt eine Methode namens OutputDebug, die offensichtlich erscheint, und natürlich habe ich sie versucht, aber es hat nicht funktioniert. Anscheinend gibt es keine Ausgabe, es sei denn, es handelt sich um einen dedizierten Editor oder eine integrierte Entwicklungsumgebung. Ziemlich nutzlos.

OutputDebug - Syntax & Usage | AutoHotkey

autohotkey print - Google Search

OutputDebug - Google Search

[Resolved] Print to Console - AutoHotkey Community

Dateien verwenden

Also habe ich vorerst eine Lösung gefunden.

Wenn Sie die Daten, die Sie vorübergehend an stdout ausgeben möchten, mit FileAppend in eine Datei - nennen wir sie Datei x - ausgeben und Datei x in bash mit cat ausgeben, können Sie im Wesentlichen stdout erhalten.

Unten ist ein Skript, das true zurückgibt, wenn das aktuelle aktive Fenster atom.exe ist, über autohotkey von bash, und andernfalls false.

Image


export AHKPRINT_STDOUT_FILE="/mnt/c/data/ahkprint.txt"
export AHKPRINT_STDOUT_IDENTIFIER="var"

ahkprint(){

: <<<'
e.g. ahkprint
'

# tmpdird

: check AHKPRINT_STDOUT_FILE file and path/dir exist then handling error

[[ ! -f "${AHKPRINT_STDOUT_FILE}" ]] && {
  touch "${AHKPRINT_STDOUT_FILE}" || {
    printf "${red}E: Couldn't make the file." ; return 1 ;
  }
}

: make null the file
> "${AHKPRINT_STDOUT_FILE}"

cat << EOT > /mnt/c/_tmp/tmp.ahk
WinGet, ${AHKPRINT_STDOUT_IDENTIFIER}, ProcessName, A
FileAppend , %${AHKPRINT_STDOUT_IDENTIFIER}% , $( wslpathr "${AHKPRINT_STDOUT_FILE}" )
EOT

psl ahk $( wslpathr /mnt/c/_tmp/tmp.ahk )

cat "${AHKPRINT_STDOUT_FILE}"

}

Übergabe von stdin (Standardeingabe) an autohotkey

Als nächsten Schritt übergeben wir stdin-Standardeingabe von bash an autohotkey.

Das folgende Skript ist eine verbesserte Version.

Image


ahkprint(){

: <<<'
e.g. ahkprint
'

# tmpdird

: If a argment defined use it else if stdin defined use it else make error

[[ -z "${1}" ]] && stdin="$(</dev/stdin)"

[[ ! -z "${1}" ]] && {
  value="${1}"
} || {
  [[ ! -z "${stdin}" ]] && {
    value="${stdin}"
  } || {
    printf "${red}No data to store to the value. at least you'd specify argment(s) or stdin." ; return 1 ;
  }
}

: check AHKPRINT_STDOUT_FILE file and path/dir exist then handling error

[[ ! -f "${AHKPRINT_STDOUT_FILE}" ]] && {
  touch "${AHKPRINT_STDOUT_FILE}" || {
    printf "${red}E: Couldn't make the file." ; return 1 ;
  }
}

: make null the file
> "${AHKPRINT_STDOUT_FILE}"

cat << EOT > /mnt/c/_tmp/tmp.ahk
WinGet, activeWinproc, ProcessName, A

WinActivate, ahk_exe ${value}
winActivateErrorLevel=%ErrorLevel%

WinWaitActive, ahk_exe ${value}

${AHKPRINT_STDOUT_IDENTIFIER} = % activeWinproc . "  " . winActivateErrorLevel

FileAppend , %${AHKPRINT_STDOUT_IDENTIFIER}% , $( wslpathr "${AHKPRINT_STDOUT_FILE}" )
EOT

psl ahk $( wslpathr /mnt/c/_tmp/tmp.ahk )

: Funktioniert nicht bei Pipe-Verarbeitung. Vermutlich läuft dies, bevor die Dateischreibverarbeitung von ahk abgeschlossen ist

# cat "${AHKPRINT_STDOUT_FILE}"

: Gegenmaßnahme für das Obige
: Überprüfen Sie, ob einige Sekunden lang Dateischreibvorgänge auftreten. Wenn Dateischreibvorgänge auftreten, cat es und beenden Sie die Schleife; wenn einige Sekunden vergehen, beenden Sie die Schleife unter der Annahme, dass die Variable und Datei leer sind

tmpdate=$(date +"%s")

while [[ "$( echo $(( $( date +"%s" ) - ${tmpdate} )) )" -lt 3 ]] ;
do

[[ ! -z "$( cat "${AHKPRINT_STDOUT_FILE}" )" ]] && {
  cat "${AHKPRINT_STDOUT_FILE}" ; break ;
}

sleep 0.1

done

# echo "hogehoge"

}

Vielseitigkeit erhöhen

Als letzten Schliff machen wir es schließlich einfach, mit beliebigen autohotkey-Skripten zu implementieren.

Ich habe den Code ein wenig geändert, sodass die Benutzerfreundlichkeit sich vom oben genannten unterscheidet, aber wenn es Ihnen nicht gefällt, versuchen Sie, den Code selbst anzupassen


ahkprint(){

: <<<'
e.g. ahkprint
'

# tmpdird

stdin="$(</dev/stdin)"

: check AHKPRINT_STDOUT_FILE file and path/dir exist then handling error

[[ ! -f "${AHKPRINT_STDOUT_FILE}" ]] && {
  touch "${AHKPRINT_STDOUT_FILE}" || {
    printf "${red}E: Couldn't make the file." ; return 1 ;
  }
}

: make null the file
> "${AHKPRINT_STDOUT_FILE}"

cat << EOT > /mnt/c/_tmp/tmp.ahk

$( eval "cat << EOT
$( echo "${stdin}" )
EOT" )

FileAppend , %${AHKPRINT_STDOUT_IDENTIFIER}% , $( wslpathr "${AHKPRINT_STDOUT_FILE}" )
EOT

psl ahk $( wslpathr /mnt/c/_tmp/tmp.ahk )

: Funktioniert nicht bei Pipe-Verarbeitung. Vermutlich läuft dies, bevor die Dateischreibverarbeitung von ahk abgeschlossen ist

# cat "${AHKPRINT_STDOUT_FILE}"

: Gegenmaßnahme für das Obige
: Überprüfen Sie, ob einige Sekunden lang Dateischreibvorgänge auftreten. Wenn Dateischreibvorgänge auftreten, cat es und beenden Sie die Schleife; wenn einige Sekunden vergehen, beenden Sie die Schleife unter der Annahme, dass die Variable und Datei leer sind

tmpdate=$(date +"%s")

while [[ "$( echo $(( $( date +"%s" ) - ${tmpdate} )) )" -lt 3 ]] ;
do

[[ ! -z "$( cat "${AHKPRINT_STDOUT_FILE}" )" ]] && {
  cat "${AHKPRINT_STDOUT_FILE}" ; break ;
}

sleep 0.1

done

}

Kurz zusammengefasst,

  • Die Konstante AHKPRINT_STDOUT_FILE gibt den Pfad der Datei an, die den von dieser Funktion verwendeten stdout-Wert vorübergehend speichert
  • Die Konstante AHKPRINT_STDOUT_IDENTIFIER gibt den Variablennamen in autohotkey an, der als stdout ausgegeben werden soll. (Standard: var)
  • stdin, Standardeingabe wird zum autohotkey-Skriptcode selbst. Darüber hinaus können bash-Argumente und Variablen in diesen Code eingebettet werden. (Folgendes ist auch möglich)
  • Wie gerade erwähnt, können Sie in Bezug auf Variablen bash-Argumente und Variablen jeweils verwenden.
  • Daten, die Sie zu stdout, Standardausgabe ausgeben möchten, werden in der Variablen var (oder dem Wert von AHKPRINT_STDOUT_IDENTIFIER oder ${AHKPRINT_STDOUT_IDENTIFIER}) im autohotkey-Skript gespeichert.
z.B.

[Code, der autohotkey-Skript generiert] | ahkprint oder ahkprint <<< “echo [autohotkey-Skript]”

(Bei Verwendung von Variablen anstelle von Argumenten)


value=typora.exe

ahkprint <<< "$(cat <<'EOT'
WinGet, activeWinproc, ProcessName, A

WinActivate, ahk_exe ${value}
winActivateErrorLevel=%ErrorLevel%

WinWaitActive, ahk_exe ${value}

var = % activeWinproc . "  " . winActivateErrorLevel
EOT
)"

Basierend auf dem obigen Code können Sie nun dasselbe mit flexiblem Code wie dem folgenden implementieren.


ahkprint "typora.exe" <<< "$(cat <<'EOT'
WinGet, activeWinproc, ProcessName, A

WinActivate, ahk_exe ${1}
winActivateErrorLevel=%ErrorLevel%

WinWaitActive, ahk_exe ${1}

var = % activeWinproc . "  " . winActivateErrorLevel
EOT
)"

Unten sind praktische Beispiele, die mit der gleichen Logik massenproduziert wurden.

Aktuelles aktives Fenster abrufen

getActiveWindowName(){

ahkprint ${@} <<< "WinGet, var, ProcessName, A"

}

Verwendungsbeispiel

[[ ! "$( getActiveWindowName )" == atom.exe ]] && { : Prozess, den Sie ausführen möchten, wenn das aktive Fenster nicht atom.exe ist hier ; }

Mauskoordinaten abrufen


getMousePos(){

  : e.g. getMousePos
  : e.g. getMousePos Relative

ahkprint ${1:-Screen} ${@:2} <<< "$( cat << 'EOT'
CoordMode, Mouse, ${1}
MouseGetPos, posX, posY
var = % posX . "  " . posY
EOT
)"

}

Verwendungsbeispiel

$  getMousePos Relative
998  510
$  getMousePos
991  923
$

Stummschaltung aufheben, wenn stumm

unmute(){

  : e.g. unmute

ahkprint ${@} <<< "$( cat << 'EOT'

;Stummschaltung aufheben, wenn stumm
SoundGet, MuteState, Master, Mute

if ErrorLevel
{
MsgBox, %ErrorLevel%
Return
}

prevMuteState = %MuteState%

if MuteState=On
{
MuteState=1
}
if MuteState=1
{
Send, {Volume_Mute}
}

SoundGet, currentMuteState, Master, Mute

var = % prevMuteState . "  " . currentMuteState

EOT
)"

}

Verwendungsbeispiel


$ unmute
Off  Off
$ unmute
On  Off
$

Lautstärke abrufen

getVolume(){

  : e.g. getVolume

ahkprint ${@} <<< "$( cat << 'EOT'
SoundGet, var
EOT
)"

}

Verwendungsbeispiel

$ getVolume
6.999999

Benutzerdefinierte Funktionen und Aliase

$ psl which ahk
C:\Program Files\AutoHotkey\AutoHotkeyU64.exe
$ psl which ahk^C
$ type psl wslpathr
psl is aliased to `/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe'
wslpathr is a function
wslpathr ()
{
    wslpath -w $(realpath $1)
}

Zusammenfassung

Ich habe bis zu dem Punkt implementiert, an dem beliebige programmierbare autohotkey-Skripte aus bash und externen Befehlen anderer Programmiersprachen ausgeführt und Ergebnisse empfangen werden.

Ich wäre froh, wenn Sie mir in Kommentaren mitteilen könnten, ob es Lücken oder bessere Methoden gibt.

Diesen Artikel teilen

Shou Arisaka 30. Okt. 2025

🔗 Links kopieren