Fix exe silent start: show activation window instead of hidden Tk parent.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -4,74 +4,113 @@ from __future__ import annotations
|
||||
|
||||
import tkinter as tk
|
||||
from tkinter import messagebox, ttk
|
||||
from typing import Optional
|
||||
|
||||
import hub_client
|
||||
from device_store import is_activated, load_device, machine_fingerprint, save_device
|
||||
from device_store import load_device, machine_fingerprint
|
||||
|
||||
|
||||
def ensure_activated(root: tk.Tk) -> bool:
|
||||
def _bring_front(win: tk.Misc) -> None:
|
||||
"""确保对话框在 Windows 上可见(避免挂在 withdraw 根窗后不显示)。"""
|
||||
try:
|
||||
win.update_idletasks()
|
||||
win.deiconify()
|
||||
win.lift()
|
||||
win.focus_force()
|
||||
win.attributes("-topmost", True)
|
||||
win.after(200, lambda: win.attributes("-topmost", False))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def ensure_activated(parent: Optional[tk.Misc] = None) -> bool:
|
||||
"""已激活且能 ping 通则通过;否则弹出激活窗。返回是否可继续。"""
|
||||
device = load_device()
|
||||
if device.get("token") and device.get("server"):
|
||||
if hub_client.ping():
|
||||
return True
|
||||
# token 失效时允许重新激活
|
||||
if not messagebox.askyesno(
|
||||
"激活校验",
|
||||
"无法连接中控或令牌失效,是否重新激活?\n选「否」将以离线模式继续(不上报复盘)。",
|
||||
parent=root,
|
||||
):
|
||||
return True
|
||||
owns_root = False
|
||||
root: tk.Misc
|
||||
if parent is not None:
|
||||
root = parent
|
||||
else:
|
||||
root = tk.Tk()
|
||||
root.title("黄金市价辅助")
|
||||
root.geometry("360x80")
|
||||
ttk.Label(root, text="正在启动…").pack(expand=True, padx=16, pady=16)
|
||||
root.update()
|
||||
owns_root = True
|
||||
|
||||
win = tk.Toplevel(root)
|
||||
win.title("激活黄金辅助")
|
||||
win.geometry("460x280")
|
||||
win.transient(root)
|
||||
win.grab_set()
|
||||
result = {"ok": False}
|
||||
try:
|
||||
if device.get("token") and device.get("server"):
|
||||
if hub_client.ping():
|
||||
return True
|
||||
_bring_front(root)
|
||||
if not messagebox.askyesno(
|
||||
"激活校验",
|
||||
"无法连接中控或令牌失效,是否重新激活?\n选「否」将以离线模式继续(不上报复盘)。",
|
||||
parent=root,
|
||||
):
|
||||
return True
|
||||
|
||||
frm = ttk.Frame(win, padding=16)
|
||||
frm.pack(fill=tk.BOTH, expand=True)
|
||||
win = tk.Toplevel(root)
|
||||
win.title("激活黄金辅助")
|
||||
win.geometry("480x300")
|
||||
win.resizable(False, False)
|
||||
# 不要 transient 到已隐藏的父窗,否则 Windows 上常不显示
|
||||
result = {"ok": False}
|
||||
|
||||
ttk.Label(frm, text="首次使用请输入中控地址与激活码(网页下载中心生成)").pack(anchor="w")
|
||||
ttk.Label(frm, text="服务器地址(例:http://192.168.1.10:5800)").pack(anchor="w", pady=(12, 4))
|
||||
var_server = tk.StringVar(value=device.get("server") or "http://127.0.0.1:5800")
|
||||
ttk.Entry(frm, textvariable=var_server, width=48).pack(fill=tk.X)
|
||||
frm = ttk.Frame(win, padding=16)
|
||||
frm.pack(fill=tk.BOTH, expand=True)
|
||||
|
||||
ttk.Label(frm, text="激活码").pack(anchor="w", pady=(12, 4))
|
||||
var_code = tk.StringVar()
|
||||
ttk.Entry(frm, textvariable=var_code, width=48).pack(fill=tk.X)
|
||||
ttk.Label(frm, text="首次使用请输入中控地址与激活码(网页下载中心生成)").pack(anchor="w")
|
||||
ttk.Label(frm, text="服务器地址(例:http://192.168.1.10:5800)").pack(anchor="w", pady=(12, 4))
|
||||
var_server = tk.StringVar(value=device.get("server") or "http://127.0.0.1:5800")
|
||||
ttk.Entry(frm, textvariable=var_server, width=48).pack(fill=tk.X)
|
||||
|
||||
ttk.Label(frm, text="本机名称(可改)").pack(anchor="w", pady=(12, 4))
|
||||
var_name = tk.StringVar(value=device.get("machine_name") or "")
|
||||
ttk.Entry(frm, textvariable=var_name, width=48).pack(fill=tk.X)
|
||||
ttk.Label(frm, text="激活码").pack(anchor="w", pady=(12, 4))
|
||||
var_code = tk.StringVar()
|
||||
ttk.Entry(frm, textvariable=var_code, width=48).pack(fill=tk.X)
|
||||
|
||||
status = ttk.Label(frm, text="", foreground="#888")
|
||||
status.pack(anchor="w", pady=(10, 0))
|
||||
ttk.Label(frm, text="本机名称(可改)").pack(anchor="w", pady=(12, 4))
|
||||
var_name = tk.StringVar(value=device.get("machine_name") or "")
|
||||
ttk.Entry(frm, textvariable=var_name, width=48).pack(fill=tk.X)
|
||||
|
||||
def do_skip():
|
||||
result["ok"] = True
|
||||
win.destroy()
|
||||
status = ttk.Label(frm, text="", foreground="#888")
|
||||
status.pack(anchor="w", pady=(10, 0))
|
||||
|
||||
def do_ok():
|
||||
server = var_server.get().strip()
|
||||
code = var_code.get().strip()
|
||||
if not server or not code:
|
||||
status.configure(text="请填写服务器与激活码", foreground="#f6465d")
|
||||
return
|
||||
try:
|
||||
hub_client.activate(server, code, machine_fingerprint(), var_name.get().strip() or "PC")
|
||||
def do_skip():
|
||||
result["ok"] = True
|
||||
messagebox.showinfo("激活成功", "已绑定账户与机器,成交将上报复盘中心。", parent=win)
|
||||
win.destroy()
|
||||
except hub_client.HubError as exc:
|
||||
status.configure(text=str(exc), foreground="#f6465d")
|
||||
|
||||
btns = ttk.Frame(frm)
|
||||
btns.pack(fill=tk.X, pady=(16, 0))
|
||||
ttk.Button(btns, text="离线使用", command=do_skip).pack(side=tk.LEFT)
|
||||
ttk.Button(btns, text="激活", command=do_ok).pack(side=tk.RIGHT)
|
||||
def do_ok():
|
||||
server = var_server.get().strip()
|
||||
code = var_code.get().strip()
|
||||
if not server or not code:
|
||||
status.configure(text="请填写服务器与激活码", foreground="#f6465d")
|
||||
return
|
||||
try:
|
||||
hub_client.activate(
|
||||
server, code, machine_fingerprint(), var_name.get().strip() or "PC"
|
||||
)
|
||||
result["ok"] = True
|
||||
messagebox.showinfo(
|
||||
"激活成功", "已绑定账户与机器,成交将上报复盘中心。", parent=win
|
||||
)
|
||||
win.destroy()
|
||||
except hub_client.HubError as exc:
|
||||
status.configure(text=str(exc), foreground="#f6465d")
|
||||
|
||||
win.protocol("WM_DELETE_WINDOW", do_skip)
|
||||
root.wait_window(win)
|
||||
return result["ok"]
|
||||
btns = ttk.Frame(frm)
|
||||
btns.pack(fill=tk.X, pady=(16, 0))
|
||||
ttk.Button(btns, text="离线使用", command=do_skip).pack(side=tk.LEFT)
|
||||
ttk.Button(btns, text="激活", command=do_ok).pack(side=tk.RIGHT)
|
||||
|
||||
win.protocol("WM_DELETE_WINDOW", do_skip)
|
||||
_bring_front(win)
|
||||
win.grab_set()
|
||||
root.wait_window(win)
|
||||
return result["ok"]
|
||||
finally:
|
||||
if owns_root:
|
||||
try:
|
||||
root.destroy()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user