Files
zWorkFlow/wechat_decrypt_launcher.py
2026-05-19 02:21:57 +08:00

140 lines
3.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""WeChatDecrypt.exe 双模式入口。
无参数时启动 Web UI带参数时分发到现有 CLI 脚本。该入口同时兼容
PyInstaller onefile 里 Web UI 子进程使用的 ``sys.executable script.py``
调用形态。
"""
import os
import runpy
import sys
MAIN_COMMANDS = {"decrypt", "export", "all", "status", "-s", "decode-images"}
HELP_COMMANDS = {"help", "-h", "--help"}
SCRIPT_ENTRYPOINTS = {
"main.py",
"monitor_web.py",
"export_all_chats.py",
"find_image_key.py",
"decrypt_sns.py",
"export_sns.py",
"find_wxwork_keys.py",
"decrypt_wxwork_db.py",
"export_wxwork_messages.py",
"voice_to_mp3.py",
"batch_decrypt_images.py",
"decrypt_db.py",
}
def _app_base_dir():
if getattr(sys, "frozen", False):
return os.path.dirname(sys.executable)
return os.path.dirname(os.path.abspath(__file__))
def _script_dir():
return getattr(sys, "_MEIPASS", _app_base_dir())
def _prepare_runtime():
base_dir = _app_base_dir()
os.environ["WECHAT_DECRYPT_APP_DIR"] = base_dir
os.chdir(base_dir)
def _configure_stdio():
for stream in (sys.stdout, sys.stderr):
if hasattr(stream, "reconfigure"):
stream.reconfigure(encoding="utf-8", errors="replace")
def print_usage(stream=None):
stream = stream or sys.stdout
stream.write(
"WeChatDecrypt.exe 用法:\n"
"\n"
" WeChatDecrypt.exe 启动 Web UI\n"
" WeChatDecrypt.exe web 启动 Web UI\n"
" WeChatDecrypt.exe status 查看状态\n"
" WeChatDecrypt.exe decrypt 提取密钥并解密数据库\n"
" WeChatDecrypt.exe export [args...] 解密并批量导出聊天\n"
" WeChatDecrypt.exe all 密钥 -> 解密 -> 导出\n"
" WeChatDecrypt.exe decode-images [args...] 批量解密 .dat 图片\n"
" WeChatDecrypt.exe export-all [args...] 直接调用 export_all_chats.py\n"
"\n"
"兼容脚本式调用:\n"
" WeChatDecrypt.exe main.py decrypt\n"
" WeChatDecrypt.exe export_all_chats.py --write-plan-csv export_plan.csv\n"
)
def _resolve_script(argv):
if not argv:
return "monitor_web.py", []
cmd = argv[0]
if cmd == "web":
return "monitor_web.py", argv[1:]
if cmd in MAIN_COMMANDS:
return "main.py", argv
if cmd == "export-all":
return "export_all_chats.py", argv[1:]
if cmd in SCRIPT_ENTRYPOINTS:
return cmd, argv[1:]
return None, None
def run_script(script, script_args):
_prepare_runtime()
script_path = os.path.join(_script_dir(), script)
if not os.path.exists(script_path):
script_path = os.path.join(_app_base_dir(), script)
if not os.path.exists(script_path):
raise FileNotFoundError(f"脚本不存在: {script_path}")
old_argv = sys.argv[:]
try:
sys.argv = [script] + list(script_args)
try:
runpy.run_path(script_path, run_name="__main__")
except SystemExit as exc:
if exc.code is None:
return 0
if isinstance(exc.code, int):
return exc.code
print(exc.code, file=sys.stderr)
return 1
return 0
finally:
sys.argv = old_argv
def dispatch(argv=None, script_runner=None, stdout=None, stderr=None):
argv = list(sys.argv[1:] if argv is None else argv)
stdout = stdout or sys.stdout
stderr = stderr or sys.stderr
runner = script_runner or run_script
if argv and argv[0] in HELP_COMMANDS:
print_usage(stdout)
return 0
script, script_args = _resolve_script(argv)
if script is None:
print_usage(stdout)
print(f"未知命令: {argv[0]}", file=stderr)
return 2
return runner(script, script_args)
def main():
_configure_stdio()
sys.exit(dispatch())
if __name__ == "__main__":
main()