I’m trying to get the path to the Anki executable file for running Anki with subprocess.Popen in add-ons.
win:anki.exe, mac:anki.app, linux:anki
addon: restart anki, self host server
Previously it could be get with shutil.which(“anki”) or sys.executable but this hack does not seem to work with the new launcher.
For now I was able to get the default anki.exe path, and the last downloaded path from Install_Dir64 on Windows, but I don’t know how to get the path of the currently running Anki yet.
Looking at the code it seems that the new launcher saves the Anki path in os.environ.get(“ANKI_LAUNCHER”) and launched from there. Is it safe to use this path cross-platform for this purpose? (or from aqt.package import launcher_executable)
like this:
import os
import subprocess
anki_exec_path = os.getenv("ANKI_LAUNCHER")
subprocess.Popen([anki_exec_path])
or,
import subprocess
from aqt.package import launcher_executable
anki_exec_path = launcher_executable()
subprocess.Popen([anki_exec_path])
Thanks for the reply. For anyone looking for the code, I tried writing code like this. (but I’ve only tested it on my Windows so I don’t know if it works on cross-platform.)
If there is a path in the user’s config, use it.
If not, get the path from os.getenv(“ANKI_LAUNCHER”).
If it cannot get it, search for the default path.
import os
import shutil
import platform
from aqt import mw
# get anki path (beta)
def get_anki_exe_path():
config = mw.addonManager.getConfig(__name__)
anki_path = None
# user config
if config.get("use_custom_anki_path", None):
anki_path = config.get("custom_anki_path", None)
if anki_path is not None:
# linux
if platform.system() == "Linux":
if os.path.exists(anki_path):
return anki_path
which_path = shutil.which(anki_path)
if which_path:
return which_path
print("[AnkiRestart] not found path?")
# win, mac
elif os.path.exists(anki_path):
return anki_path
# ANKI_LAUNCHER (new launcher)
anki_path = os.getenv("ANKI_LAUNCHER")
if anki_path is not None and os.path.exists(anki_path):
return anki_path
# default path
if platform.system() == "Windows":
anki_path = get_anki_path_win()
elif platform.system() == "Darwin":
mac_default_path = '/Applications/Anki.app'
if os.path.exists(mac_default_path):
anki_path = mac_default_path
else: # Linux
linux_default_path = shutil.which("anki")
if linux_default_path:
anki_path = linux_default_path
return None
# for win
def get_anki_path_win():
# default path
local_appdata = os.environ.get("LOCALAPPDATA", "")
if local_appdata:
default_path = os.path.join(local_appdata, "Programs", "Anki", "anki.exe")
if os.path.exists(default_path):
return default_path
try: # registry "Install_Dir64"
import winreg
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Anki") as key:
install_dir = winreg.QueryValueEx(key, "Install_Dir64")[0]
registry_path = os.path.join(install_dir, "anki.exe")
if os.path.exists(registry_path):
return registry_path
except Exception as e:
print(f"[AnkiRestart] Install_Dir64: {e}")
pass
return None