Skip to content

Instantly share code, notes, and snippets.

@roflsunriz
Last active February 5, 2025 13:02
Show Gist options
  • Save roflsunriz/095dd7369862fce5becd5f93a39957a8 to your computer and use it in GitHub Desktop.
Save roflsunriz/095dd7369862fce5becd5f93a39957a8 to your computer and use it in GitHub Desktop.
WSAInstallAPK.py : GUI Program that performs installing APK for WSA (Windows Android Subsystem)
import tkinter as tk
from tkinter import scrolledtext, filedialog
import subprocess
import threading
import os
import json
# 言語用の辞書の定義
LANGUAGES = {
"ja": {
"title": "Windows Android Subsystem 用 GUI実行ツール のじゃ",
"adb_folder": "adbフォルダの場所:",
"apk_path": "インストールするAPKパス:",
"log_label": "ログ:",
"run": "実行",
"exit": "終了",
"browse": "参照",
"language": "言語選択:",
},
"en": {
"title": "Windows Android Subsystem GUI Tool",
"adb_folder": "adb Folder Path:",
"apk_path": "APK Path:",
"log_label": "Log:",
"run": "Run",
"exit": "Exit",
"browse": "Browse",
"language": "Language:",
}
}
LOG_MESSAGES = {
"ja": {
"going_to_dir": "指定ディレクトリ: {adb_path} に移動中のじゃ...",
"error_adb": "エラー: adbパスが存在しないのじゃ!",
"command_execute": "コマンド実行: {cmd}",
"error": "エラー: {error}",
"install_apk": "インストールするAPK: {apk_path}",
"error_apk": "エラー: APKファイルが存在しないのじゃ!",
"exception": "例外発生: {e}",
},
"en": {
"going_to_dir": "Changing current directory to: {adb_path} ...",
"error_adb": "Error: adb folder does not exist!",
"command_execute": "Executing command: {cmd}",
"error": "Error: {error}",
"install_apk": "Installing APK: {apk_path}",
"error_apk": "Error: APK file does not exist!",
"exception": "Exception occurred: {e}",
}
}
SETTINGS_FILE = "settings.json"
def load_settings():
"""設定ファイルから設定値を読み込むのじゃ"""
defaults = {"adb_folder": r"C:\platform-tools", "apk_path": ""}
if os.path.isfile(SETTINGS_FILE):
try:
with open(SETTINGS_FILE, "r", encoding="utf-8") as f:
data = json.load(f)
defaults.update(data)
except Exception as e:
print("設定読み込み失敗:", e)
return defaults
def save_settings(adb_folder, apk_path):
"""現在の設定値を設定ファイルに保存するのじゃ"""
data = {"adb_folder": adb_folder, "apk_path": apk_path}
try:
with open(SETTINGS_FILE, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=4)
except Exception as e:
print("設定保存失敗:", e)
def append_log(log_widget, message):
log_widget.configure(state='normal')
log_widget.insert(tk.END, message + "\n")
log_widget.see(tk.END)
log_widget.configure(state='disabled')
def run_commands(adb_path, apk_path, log_widget, run_button, language_var):
lang = language_var.get()
trans = LOG_MESSAGES[lang]
try:
run_button.config(state=tk.DISABLED)
append_log(log_widget, trans["going_to_dir"].format(adb_path=adb_path))
if not os.path.isdir(adb_path):
append_log(log_widget, trans["error_adb"])
run_button.config(state=tk.NORMAL)
return
connect_cmd = ["adb", "connect", "127.0.0.1:58526"]
append_log(log_widget, trans["command_execute"].format(cmd=" ".join(connect_cmd)))
result = subprocess.run(connect_cmd, cwd=adb_path, capture_output=True, text=True)
append_log(log_widget, result.stdout)
if result.stderr:
append_log(log_widget, trans["error"].format(error=result.stderr))
append_log(log_widget, trans["install_apk"].format(apk_path=apk_path))
if not os.path.isfile(apk_path):
append_log(log_widget, trans["error_apk"])
run_button.config(state=tk.NORMAL)
return
install_cmd = ["adb", "install", apk_path]
append_log(log_widget, trans["command_execute"].format(cmd=" ".join(install_cmd)))
result = subprocess.run(install_cmd, cwd=adb_path, capture_output=True, text=True)
append_log(log_widget, result.stdout)
if result.stderr:
append_log(log_widget, trans["error"].format(error=result.stderr))
except Exception as e:
append_log(log_widget, trans["exception"].format(e=str(e)))
finally:
run_button.config(state=tk.NORMAL)
def select_apk(entry_apk, trans):
filepath = filedialog.askopenfilename(filetypes=[("APK files", "*.apk")])
if filepath:
entry_apk.delete(0, tk.END)
entry_apk.insert(0, filepath)
def select_adb_folder(entry_adb):
"""adbフォルダー選択用のダイアログを開くのじゃ"""
folder = filedialog.askdirectory()
if folder:
entry_adb.delete(0, tk.END)
entry_adb.insert(0, folder)
def update_language(root, lbl_adb, lbl_apk, lbl_log, btn_run, btn_exit, btn_browse_apk, btn_browse_adb, lbl_lang, language_var):
lang = language_var.get()
root.title(LANGUAGES[lang]["title"])
lbl_adb.config(text=LANGUAGES[lang]["adb_folder"])
lbl_apk.config(text=LANGUAGES[lang]["apk_path"])
lbl_log.config(text=LANGUAGES[lang]["log_label"])
btn_run.config(text=LANGUAGES[lang]["run"])
btn_exit.config(text=LANGUAGES[lang]["exit"])
btn_browse_apk.config(text=LANGUAGES[lang]["browse"])
btn_browse_adb.config(text=LANGUAGES[lang]["browse"])
lbl_lang.config(text=LANGUAGES[lang]["language"])
def main():
root = tk.Tk()
# ここで language_var を生成するのじゃ
language_var = tk.StringVar(root, value="ja")
settings = load_settings()
root.geometry("600x400")
root.title(LANGUAGES[language_var.get()]["title"])
frame = tk.Frame(root)
frame.pack(padx=10, pady=10, fill=tk.X)
# 言語選択フレームの追加
lang_frame = tk.Frame(root)
lang_frame.pack(padx=10, pady=5, fill=tk.X)
lbl_lang = tk.Label(lang_frame, text=LANGUAGES[language_var.get()]["language"])
lbl_lang.grid(row=0, column=0, sticky=tk.W)
tk.Radiobutton(lang_frame, text="日本語", variable=language_var, value="ja",
command=lambda: update_language(root, lbl_adb, lbl_apk, lbl_log, btn_run, btn_exit, btn_browse_apk, btn_browse_adb, lbl_lang, language_var)).grid(row=0, column=1)
tk.Radiobutton(lang_frame, text="English", variable=language_var, value="en",
command=lambda: update_language(root, lbl_adb, lbl_apk, lbl_log, btn_run, btn_exit, btn_browse_apk, btn_browse_adb, lbl_lang, language_var)).grid(row=0, column=2)
# adbフォルダ指定
lbl_adb = tk.Label(frame, text=LANGUAGES[language_var.get()]["adb_folder"])
lbl_adb.grid(row=0, column=0, sticky=tk.W)
entry_adb = tk.Entry(frame, width=50)
entry_adb.grid(row=0, column=1, padx=5, pady=5)
entry_adb.insert(0, settings["adb_folder"])
btn_browse_adb = tk.Button(frame, text=LANGUAGES[language_var.get()]["browse"],
command=lambda: select_adb_folder(entry_adb))
btn_browse_adb.grid(row=0, column=2, padx=5, pady=5)
# apk指定
lbl_apk = tk.Label(frame, text=LANGUAGES[language_var.get()]["apk_path"])
lbl_apk.grid(row=1, column=0, sticky=tk.W)
entry_apk = tk.Entry(frame, width=50)
entry_apk.grid(row=1, column=1, padx=5, pady=5)
entry_apk.insert(0, settings["apk_path"])
btn_browse_apk = tk.Button(frame, text=LANGUAGES[language_var.get()]["browse"],
command=lambda: select_apk(entry_apk, LANGUAGES[language_var.get()]))
btn_browse_apk.grid(row=1, column=2, padx=5, pady=5)
# ログエリア
lbl_log = tk.Label(root, text=LANGUAGES[language_var.get()]["log_label"])
lbl_log.pack(anchor=tk.W, padx=10)
log_text = scrolledtext.ScrolledText(root, state='disabled', wrap=tk.WORD, height=15)
log_text.pack(padx=10, pady=5, fill=tk.BOTH, expand=True)
button_frame = tk.Frame(root)
button_frame.pack(pady=5)
btn_run = tk.Button(button_frame, text=LANGUAGES[language_var.get()]["run"], width=10,
command=lambda: threading.Thread(target=run_commands, args=(
entry_adb.get(), entry_apk.get(), log_text, btn_run, language_var)).start())
btn_run.grid(row=0, column=0, padx=5)
# 終了時に設定を保存するラッパー関数に変更
def exit_program():
save_settings(entry_adb.get(), entry_apk.get())
root.destroy()
btn_exit = tk.Button(button_frame, text=LANGUAGES[language_var.get()]["exit"], width=10, command=exit_program)
btn_exit.grid(row=0, column=1, padx=5)
root.mainloop()
if __name__ == "__main__":
main()
@roflsunriz
Copy link
Author

roflsunriz commented Feb 1, 2025

How to use:

  1. Install latest python.
  2. double click .pyw file.
  3. Specify platform-tools folder.
  4. Specify APK file.
  5. Run. This installs APK.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment