Files
2026-05-15 19:47:31 +08:00

7.3 KiB

长安语言刷入工具 (Changan Language Flashing Tool)

Overview

A Windows GUI tool suite (Python 3.6+ / tkinter) for flashing multi-language APKs onto Android-based vehicle infotainment systems. Built by 宜宾科宜科技有限公司.

The suite contains 5 tool variants, each targeting a different vehicle model. All share the same ADKAPKGUI class architecture with model-specific customizations. Authorization is VIN-based via a cloud API.

Tool file Vehicle Window title Pack script
app.py 启源Q07 长安语言安装工具 pack_q07.bat
S05.py 深蓝S05 深蓝S05多语言安装 pack_s05.bat
X5plusTool.py X5plus 适用于X5plus多语言安装 pack_x5plus.bat
app-install.py 长安逸动 (通用) 长安语言刷入工具 pack_common.bat
app-yidong.py 长安逸动 长安逸动语言刷入工具 pack_yidong.bat

Project structure

├── app.py                  # 启源Q07 tool
├── S05.py                  # 深蓝S05 tool
├── X5plusTool.py           # X5plus tool
├── app-install.py          # 逸动通用 tool
├── app-yidong.py           # 逸动 tool
├── pack_q07.bat            # Q07 pack script
├── pack_s05.bat            # S05 pack script
├── pack_x5plus.bat         # X5plus pack script
├── pack_common.bat         # 逸动通用 pack script
├── pack_yidong.bat         # 逸动 pack script
├── test_extract.py         # Standalone test for package.bin extraction
├── app.ico                 # Application icon
├── package.bin             # Encrypted ZIP (not in repo)
├── adb.exe                 # Bundled ADB
├── AdbWinApi.dll           # ADB dependency
├── AdbWinUsbApi.dll        # ADB dependency
└── .vscode/
    └── settings.json

Architecture

Single-file design

Each tool is a single Python file under the ADKAPKGUI class. No MVC separation — the class handles GUI, business logic, ADB operations, network calls, and file extraction.

Threading model

  • Main thread: tkinter event loop (root.mainloop())
  • Background threads: All user-triggered operations spawn threading.Thread(target=..., daemon=True)
  • Thread-safety: UI mutations via self.run_on_ui_thread(func, ...)self.root.after(0, func, ...). Internal _impl methods are the actual tkinter-touching implementations.

ADB operations

  • run_adb_command(command) — standard ADB commands; auto-substitutes adb with bundled adb.exe path when frozen
  • run_adb_shell(shell_command) — only in app-install.py / app-yidong.py; shells into device with auto-password adb36987

ADB path is portable: self.adb resolves to sys._MEIPASS/adb.exe when frozen (PyInstaller bundle), or 'adb' in development.

Authentication flow

  1. ADB detects device → reads VIN (ca_vin_info or VIN; 逸动 uses ca.car.vin)
  2. VIN sent to https://api.changan.softwindy.cn/api/authorizations/auth-check?vin=...
  3. Package password from https://api.changan.softwindy.cn/api/authorizations/package-key?vin=...
  4. Password used to decrypt package.bin

Package extraction

  • package.bin is a password-protected ZIP (AES via pyzipper, fallback to zipfile)
  • Extracted to %LOCALAPPDATA%\.cache\system\.android\apps_cache_{variant} (hidden via attrib +h)
  • Each tool has its own cache folder to avoid conflicts:
    • app.py → apps_cache_Q07
    • S05.py → apps_cache_S05
    • X5plusTool.py → apps_cache_X5plus
    • app-install.py → apps_cache_common
    • app-yidong.py → apps_cache_common (default)
  • Extracted APKs in app/ pushed to /system/app/, priv-app/ to /system/priv-app/

Device status monitoring

Background daemon thread runs adb devices every 5 seconds to detect connect/disconnect events.

GUI layout (650x640 dark theme for most; 650x550 for 逸动)

Section Contents
Title bar Vehicle model + company subtitle
Password query Hidden VIN→password lookup (S05, app-install only)
Button row 1 获取权限 (Q07/S05), 刷入语言包, 安装App, 语言设置
Button row 2 时区设置, 安卓设置, 重启设备, 禁用升级
Status bar Connection dot, VIN, Auth status, Refresh button
Tips Usage warnings
Progress Extraction + push progress (hidden by default)
Log area ScrolledText with tags (INFO/SUCCESS/ERROR/WARNING/CMD), 清空日志 button in title bar

Key features

Install App (unified single/batch)

"安装App" button uses filedialog.askopenfilenames for multi-file selection, replacing old separate "单个安装" and "批量安装" buttons. Select 1 or more APKs and installs all in one pass (adb install -r).

Debug mode (hidden)

Press Ctrl+Shift+D → password zxch5200 to enter debug mode:

  • Bypasses device connection and authorization checks (UI shows "已连接" / "已授权")
  • Logs all raw ADB commands and output to the log panel
  • Exiting debug mode auto-refreshes real device state

Language quick-set

Popup with 8 one-click locale switches (zh-CN, en-US, ru-RU, fr-FR, es-ES, pt-BR, it-IT, ar-SA). Also links to native Android language settings. Changes take effect after reboot.

Model-specific behaviors

Feature Q07 (app.py) S05 (S05.py) X5plus (X5plusTool.py) 逸动 (app-install/yidong)
Root perm Y Y N (no btn_root) N
priv-app Y Y Y N (app only)
ADB shell Standard Standard Standard Auto-password adb36987
VIN key ca_vin_info/VIN ca_vin_info/VIN ca_vin_info/VIN ca.car.vin
Old app cleanup N N Y (5 packages) N
Font push N N Y (FZLTHPro) N
Overlay enable N N N N (removed)
Password query N Y N Y
Factory hints N Y Y (dynamic pwd) Y

Build process

Each pack_*.bat follows the same pipeline:

  1. Install deps: pyinstaller, cython, pyzipper
  2. Clean old build dirs
  3. Cython compile: {source}.py_core.pyd
  4. Copy resources: adb.exe, DLLs, app.ico
  5. PyInstaller: single .exe with --uac-admin, bundling _core.pyd + ADB + DLLs
  6. Fallback to normal PyInstaller if Cython fails

Output exe is self-contained — bundles adb.exe and DLLs via sys._MEIPASS, no external ADB needed.

Key behaviors to preserve

  1. Thread safety: Never call tkinter from background threads — always use run_on_ui_thread
  2. VIN-based auth: Authorization required before push; flow must remain intact
  3. Silent extraction: Auto-extract package.bin without user step
  4. ADB portability: self.adb resolves to bundled exe path; all commands go through run_adb_command
  5. vecentek.model: Set to 1 before install, 0 after
  6. Chinese encoding: # -*- coding: utf-8 -*- throughout
  7. Debug mode: self.debug_mode flag gates auth/connection bypass and verbose logging
  8. Separate cache dirs: Each tool extracts to its own cache folder

Known issues

  • test_extract.py hardcodes password — should fetch from API
  • on_disable_upgrade uses findstr (Windows-specific)
  • Exception handling is minimal in many places (bare except: pass)
  • 逸动 tools (app-install/yidong) use subprocess.Popen with stdin password injection — fragile