import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox
import subprocess
import time
import keyboard
import pyautogui
import threading
import re
import webbrowser
#pip install keyboard pyautogui


class DigitalExecutorApp:
    def __init__(self, root):
        self.root = root
        self.root.title("数字执行机器人 v3.0 - 全键盘鼠标支持")
        self.root.geometry("800x700")
        
        # 创建界面组件
        self.create_widgets()
        
        # 初始化状态
        self.text7_visible = True
        
        # 初始化指令映射
        self.init_command_mapping()
        
        # 显示启动信息
        self.log_message("数字执行机器人 v3.0 已启动")
        self.log_message("支持 1位、2位、3位数指令映射")
        self.log_message("使用 '-' 作为分隔符,例如: 0-a-1-d-21-2-Z-cc-11-234-e-w")
        self.log_message("点击 '帮助' 查看完整指令列表")
        
    def init_command_mapping(self):
        """初始化所有指令映射(单字符、2位和3位数)"""
        # ============ 单字符映射 ============
        self.char_map = {
            # 小写字母 - 基本按键
            "a": "tab",          # Tab键
            "b": "enter",        # Enter键
            "c": "space",        # 空格键
            "d": "esc",          # ESC键
            "e": "ctrl+a",       # 全选
            "f": "ctrl+c",       # 复制
            "g": "ctrl+v",       # 粘贴
            "h": "alt+tab",      # 切换窗口
            "i": "alt+n",        # Alt+N
            "j": "alt+x",        # Alt+X
            "k": "f1",           # F1
            "l": "f2",           # F2
            "m": "f3",           # F3
            "n": "f4",           # F4
            "o": "f5",           # F5
            "p": "f6",           # F6
            "q": "f7",           # F7
            "r": "f8",           # F8
            "s": "f9",           # F9
            "t": "f10",          # F10
            "u": "f11",          # F11
            "v": "f12",          # F12
            "w": "backspace",    # 退格键
            "x": "home",         # Home键
            "y": "end",          # End键
            "z": "win",          # Windows键
            
            # 大写字母 - 组合键
            "A": "delete",       # Delete键
            "B": "ctrl+a",       # Ctrl+A
            "C": "ctrl+c",       # Ctrl+C
            "D": "ctrl+v",       # Ctrl+V
            "E": "shift",        # Shift键
            "F": "alt",          # Alt键
            "G": "win+d",        # 显示桌面
            "H": "win+e",        # 打开文件资源管理器
            "I": "win+m",        # 最小化所有窗口
            "J": "shift+tab",    # Shift+Tab
            "K": "ctrl+tab",     # Ctrl+Tab
            "L": "ctrl+f11",     # Ctrl+F11
            "M": "ctrl+o",       # Ctrl+O
            "N": "alt+f4",       # 关闭窗口
            "O": "alt+space",    # Alt+Space
            "P": "ctrl+esc",     # Ctrl+Esc
            "Q": "ctrl+alt+delete",  # Ctrl+Alt+Del
            "R": "shift+delete", # Shift+Delete
            "S": "ctrl+s",       # 保存
            "T": "shift+f10",    # Shift+F10 (右键菜单)
            "U": "ctrl+f4",      # Ctrl+F4
            "V": "alt",          # Alt
            "W": "shift+f10",    # Shift+F10
            "X": "ctrl+z",       # 撤销
            "Y": "ctrl+y",       # 重做
            "Z": "ctrl+f11",     # Ctrl+F11
        }
        
        # ============ 2位数映射 (00-99) ============
        self.two_digit_map = {
            # 00-09: Ctrl+数字
            "00": "ctrl+0", "01": "ctrl+1", "02": "ctrl+2", "03": "ctrl+3",
            "04": "ctrl+4", "05": "ctrl+5", "06": "ctrl+6", "07": "ctrl+7",
            "08": "ctrl+8", "09": "ctrl+9",
            
            # 10-19: Alt+数字
            "10": "alt+0", "11": "alt+1", "12": "alt+2", "13": "alt+3",
            "14": "alt+4", "15": "alt+5", "16": "alt+6", "17": "alt+7",
            "18": "alt+8", "19": "alt+9",
            
            # 20-29: Shift+数字
            "20": "shift+0", "21": "shift+1", "22": "shift+2", "23": "shift+3",
            "24": "shift+4", "25": "shift+5", "26": "shift+6", "27": "shift+7",
            "28": "shift+8", "29": "shift+9",
            
            # 30-39: Win+数字
            "30": "win+0", "31": "win+1", "32": "win+2", "33": "win+3",
            "34": "win+4", "35": "win+5", "36": "win+6", "37": "win+7",
            "38": "win+8", "39": "win+9",
            
            # 40-49: Ctrl+Shift+数字
            "40": "ctrl+shift+0", "41": "ctrl+shift+1", "42": "ctrl+shift+2",
            "43": "ctrl+shift+3", "44": "ctrl+shift+4", "45": "ctrl+shift+5",
            "46": "ctrl+shift+6", "47": "ctrl+shift+7", "48": "ctrl+shift+8",
            "49": "ctrl+shift+9",
            
            # 50-59: Alt+Shift+数字
            "50": "alt+shift+0", "51": "alt+shift+1", "52": "alt+shift+2",
            "53": "alt+shift+3", "54": "alt+shift+4", "55": "alt+shift+5",
            "56": "alt+shift+6", "57": "alt+shift+7", "58": "alt+shift+8",
            "59": "alt+shift+9",
            
            # 60-69: Ctrl+Alt+数字
            "60": "ctrl+alt+0", "61": "ctrl+alt+1", "62": "ctrl+alt+2",
            "63": "ctrl+alt+3", "64": "ctrl+alt+4", "65": "ctrl+alt+5",
            "66": "ctrl+alt+6", "67": "ctrl+alt+7", "68": "ctrl+alt+8",
            "69": "ctrl+alt+9",
            
            # 70-79: 功能键
            "70": "f1", "71": "f2", "72": "f3", "73": "f4",
            "74": "f5", "75": "f6", "76": "f7", "77": "f8",
            "78": "f9", "79": "f10",
            
            # 80-89: 方向键和编辑键
            "80": "up",          # 上箭头
            "81": "down",        # 下箭头
            "82": "left",        # 左箭头
            "83": "right",       # 右箭头
            "84": "pageup",      # PageUp
            "85": "pagedown",    # PageDown
            "86": "home",        # Home
            "87": "end",         # End
            "88": "insert",      # Insert
            "89": "delete",      # Delete
            
            # 90-99: 多媒体键
            "90": "volumeup",    # 音量+
            "91": "volumedown",  # 音量-
            "92": "volumemute",  # 静音
            "93": "playpause",   # 播放/暂停
            "94": "stop",        # 停止
            "95": "nexttrack",   # 下一曲
            "96": "prevtrack",   # 上一曲
            "97": "mediaselect", # 媒体选择
            "98": "printscreen", # 截图
            "99": "pause",       # Pause/Break
        }
        
        # ============ 3位数映射 (000-999) ============
        self.three_digit_map = {
            # 鼠标操作 100-199
            "100": "mouse_left",      # 鼠标左键
            "101": "mouse_right",     # 鼠标右键
            "102": "mouse_middle",    # 鼠标中键
            "103": "mouse_left_double", # 鼠标左键双击
            "104": "mouse_scroll_up",   # 滚轮向上
            "105": "mouse_scroll_down", # 滚轮向下
            "106": "mouse_move_up",     # 鼠标向上移动
            "107": "mouse_move_down",   # 鼠标向下移动
            "108": "mouse_move_left",   # 鼠标向左移动
            "109": "mouse_move_right",  # 鼠标向右移动
            "110": "mouse_click_hold",  # 鼠标按住
            "111": "mouse_click_release", # 鼠标释放
            
            # 键盘扩展 200-299
            "200": "ctrl",         # Ctrl
            "201": "alt",          # Alt
            "202": "shift",        # Shift
            "203": "win",          # Win
            "204": "ctrl+shift",   # Ctrl+Shift
            "205": "ctrl+alt",     # Ctrl+Alt
            "206": "alt+shift",    # Alt+Shift
            "207": "ctrl+alt+shift", # Ctrl+Alt+Shift
            "208": "ctrl+win",     # Ctrl+Win
            "209": "alt+win",      # Alt+Win
            "210": "win+shift",    # Win+Shift
            "211": "ctrl+alt+win", # Ctrl+Alt+Win
            "212": "ctrl+shift+win", # Ctrl+Shift+Win
            "213": "alt+shift+win", # Alt+Shift+Win
            "214": "ctrl+alt+shift+win", # Ctrl+Alt+Shift+Win
            
            # 文本操作 300-399
            "300": "ctrl+a",       # 全选
            "301": "ctrl+c",       # 复制
            "302": "ctrl+v",       # 粘贴
            "303": "ctrl+x",       # 剪切
            "304": "ctrl+z",       # 撤销
            "305": "ctrl+y",       # 重做
            "306": "ctrl+f",       # 查找
            "307": "ctrl+h",       # 替换
            "308": "ctrl+s",       # 保存
            "309": "ctrl+o",       # 打开
            "310": "ctrl+n",       # 新建
            "311": "ctrl+p",       # 打印
            "312": "ctrl+w",       # 关闭
            "313": "ctrl+shift+esc", # 任务管理器
            
            # 系统操作 400-499
            "400": "win+d",        # 显示桌面
            "401": "win+e",        # 文件资源管理器
            "402": "win+r",        # 运行
            "403": "win+m",        # 最小化所有
            "404": "win+shift+m",  # 还原所有
            "405": "win+l",        # 锁定电脑
            "406": "win+p",        # 投影设置
            "407": "win+i",        # 设置
            "408": "win+s",        # 搜索
            "409": "win+x",        # 快速链接菜单
            "410": "alt+f4",       # 关闭窗口
            "411": "alt+tab",      # 切换窗口
            "412": "ctrl+alt+delete", # 安全选项
            "413": "ctrl+shift+esc", # 任务管理器
            "414": "win+tab",      # 任务视图
            "415": "alt+space",    # 窗口菜单
            
            # 组合键 500-599
            "500": "ctrl+alt+0", "501": "ctrl+alt+1", "502": "ctrl+alt+2",
            "503": "ctrl+alt+3", "504": "ctrl+alt+4", "505": "ctrl+alt+5",
            "506": "ctrl+alt+6", "507": "ctrl+alt+7", "508": "ctrl+alt+8",
            "509": "ctrl+alt+9",
            
            "510": "ctrl+shift+0", "511": "ctrl+shift+1", "512": "ctrl+shift+2",
            "513": "ctrl+shift+3", "514": "ctrl+shift+4", "515": "ctrl+shift+5",
            "516": "ctrl+shift+6", "517": "ctrl+shift+7", "518": "ctrl+shift+8",
            "519": "ctrl+shift+9",
            
            "520": "alt+shift+0", "521": "alt+shift+1", "522": "alt+shift+2",
            "523": "alt+shift+3", "524": "alt+shift+4", "525": "alt+shift+5",
            "526": "alt+shift+6", "527": "alt+shift+7", "528": "alt+shift+8",
            "529": "alt+shift+9",
            
            # 特殊功能 600-699
            "600": "sleep",        # 休眠
            "601": "power",        # 关机
            "602": "restart",      # 重启
            "603": "logout",       # 注销
            "604": "lock",         # 锁定
            "605": "switch_user",  # 切换用户
            
            # 应用程序 700-799
            "700": "calc",         # 计算器
            "701": "notepad",      # 记事本
            "702": "paint",        # 画图
            "703": "cmd",          # 命令提示符
            "704": "explorer",     # 资源管理器
            "705": "taskmgr",      # 任务管理器
            "706": "control",      # 控制面板
            "707": "snippingtool", # 截图工具
            
            # 自定义文本 800-899 (模拟输入)
            "800": "text_hello",   # 输入"hello"
            "801": "text_world",   # 输入"world"
            "802": "text_test",    # 输入"test"
            "803": "text_123",     # 输入"123"
            "804": "text_abc",     # 输入"abc"
            "805": "text_password", # 输入"password"
            
            # 特殊符号 900-999
            "900": "key_+",        # 加号
            "901": "key_-",        # 减号
            "902": "key_*",        # 星号
            "903": "key_/",        # 斜杠
            "904": "key_=",        # 等号
            "905": "key_.",        # 点号
            "906": "key_,",        # 逗号
            "907": "key_;",        # 分号
            "908": "key_:",        # 冒号
            "909": "key_?",        # 问号
            "910": "key_!",        # 感叹号
            "911": "key_@",        # @符号
            "912": "key_#",        # #符号
            "913": "key_$",        # $符号
            "914": "key_%",        # %符号
            "915": "key_^",        # ^符号
            "916": "key_&",        # &符号
            "917": "key_(",        # 左括号
            "918": "key_)",        # 右括号
            "919": "key_~",        # ~符号
            "920": "key_`",        # `符号
            "921": "key_[",        # 左方括号
            "922": "key_]",        # 右方括号
            "923": "key_\\",       # 反斜杠
            "924": "key_{",        # 左花括号
            "925": "key_}",        # 右花括号
            "926": "key_|",        # 竖线
            "927": "key_<",        # 小于号
            "928": "key_>",        # 大于号
            "929": "key_\"",       # 双引号
            "930": "key_'",        # 单引号
        }
        
    def create_widgets(self):
        """创建界面组件"""
        # 主框架
        main_frame = ttk.Frame(self.root, padding="10")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 工具栏
        toolbar = ttk.Frame(main_frame)
        toolbar.grid(row=0, column=0, columnspan=4, sticky=(tk.W, tk.E), pady=(0, 10))
        
        ttk.Button(toolbar, text="📖 帮助", command=self.show_help).pack(side=tk.LEFT, padx=2)
        ttk.Button(toolbar, text="📋 示例", command=self.show_examples).pack(side=tk.LEFT, padx=2)
        ttk.Button(toolbar, text="🔄 重置", command=self.reset_all).pack(side=tk.LEFT, padx=2)
        ttk.Button(toolbar, text="❌ 清空日志", command=self.clear_log).pack(side=tk.LEFT, padx=2)
        
        # 第1行:程序路径1 + 启动按钮
        ttk.Label(main_frame, text="程序路径1:").grid(row=1, column=0, sticky=tk.W, pady=5)
        self.text1 = ttk.Entry(main_frame, width=50)
        self.text1.grid(row=1, column=1, columnspan=2, sticky=(tk.W, tk.E), pady=5)
        self.btn_start1 = ttk.Button(main_frame, text="▶ 启动1", command=self.command1_click)
        self.btn_start1.grid(row=1, column=3, padx=5, pady=5)
        
        # 第2行:程序路径2
        ttk.Label(main_frame, text="程序路径2:").grid(row=2, column=0, sticky=tk.W, pady=5)
        self.text2 = ttk.Entry(main_frame, width=50)
        self.text2.grid(row=2, column=1, columnspan=2, sticky=(tk.W, tk.E), pady=5)
        self.btn_start2 = ttk.Button(main_frame, text="▶ 启动2", command=self.command3_click)
        self.btn_start2.grid(row=2, column=3, padx=5, pady=5)
        
        # 第3行:程序路径3
        ttk.Label(main_frame, text="程序路径3:").grid(row=3, column=0, sticky=tk.W, pady=5)
        self.text5 = ttk.Entry(main_frame, width=50)
        self.text5.grid(row=3, column=1, columnspan=2, sticky=(tk.W, tk.E), pady=5)
        self.btn_start3 = ttk.Button(main_frame, text="▶ 启动3", command=self.command4_click)
        self.btn_start3.grid(row=3, column=3, padx=5, pady=5)
        
        # 第4行:程序路径4
        ttk.Label(main_frame, text="程序路径4:").grid(row=4, column=0, sticky=tk.W, pady=5)
        self.text6 = ttk.Entry(main_frame, width=50)
        self.text6.grid(row=4, column=1, columnspan=2, sticky=(tk.W, tk.E), pady=5)
        self.btn_start4 = ttk.Button(main_frame, text="▶ 启动4", command=self.command5_click)
        self.btn_start4.grid(row=4, column=3, padx=5, pady=5)
        
        # 第5行:延迟时间和执行次数
        param_frame = ttk.Frame(main_frame)
        param_frame.grid(row=5, column=0, columnspan=4, sticky=(tk.W, tk.E), pady=5)
        
        ttk.Label(param_frame, text="延迟(毫秒):").pack(side=tk.LEFT, padx=(0, 5))
        self.text3 = ttk.Entry(param_frame, width=10)
        self.text3.pack(side=tk.LEFT, padx=(0, 20))
        self.text3.insert(0, "100")
        
        ttk.Label(param_frame, text="执行次数:").pack(side=tk.LEFT, padx=(0, 5))
        self.text_repeat = ttk.Entry(param_frame, width=10)
        self.text_repeat.pack(side=tk.LEFT, padx=(0, 20))
        self.text_repeat.insert(0, "1")
        
        ttk.Label(param_frame, text="分隔符:").pack(side=tk.LEFT, padx=(0, 5))
        self.text_separator = ttk.Entry(param_frame, width=5)
        self.text_separator.pack(side=tk.LEFT)
        self.text_separator.insert(0, "-")
        
        # 第6行:指令序列
        ttk.Label(main_frame, text="指令序列:").grid(row=6, column=0, sticky=tk.W, pady=5)
        self.text4 = ttk.Entry(main_frame, width=50)
        self.text4.grid(row=6, column=1, columnspan=2, sticky=(tk.W, tk.E), pady=5)
        self.btn_execute = ttk.Button(main_frame, text="⚡ 执行指令", command=self.command2_click)
        self.btn_execute.grid(row=6, column=3, padx=5, pady=5)
        
        # 第7行:执行状态
        self.status_label = ttk.Label(main_frame, text="就绪", foreground="green")
        self.status_label.grid(row=7, column=0, columnspan=4, sticky=tk.W, pady=5)
        
        # 第8行:日志区域
        ttk.Label(main_frame, text="执行日志:").grid(row=8, column=0, sticky=tk.W, pady=5)
        
        log_frame = ttk.Frame(main_frame)
        log_frame.grid(row=9, column=0, columnspan=4, sticky=(tk.W, tk.E, tk.N, tk.S), pady=5)
        
        self.text7 = scrolledtext.ScrolledText(log_frame, width=80, height=12, 
                                               font=("Consolas", 9), state='disabled')
        self.text7.pack(fill=tk.BOTH, expand=True)
        
        # 复选框控制日志显示
        control_frame = ttk.Frame(main_frame)
        control_frame.grid(row=10, column=0, columnspan=4, sticky=tk.W, pady=5)
        
        self.check1 = tk.IntVar(value=1)
        self.chk_show_log = ttk.Checkbutton(control_frame, text="显示日志", 
                                           variable=self.check1, command=self.check1_click)
        self.chk_show_log.pack(side=tk.LEFT, padx=5)
        
        self.chk_auto_scroll = tk.IntVar(value=1)
        ttk.Checkbutton(control_frame, text="自动滚动", 
                       variable=self.chk_auto_scroll).pack(side=tk.LEFT, padx=5)
        
        # 进度条
        self.progress = ttk.Progressbar(control_frame, mode='indeterminate', length=100)
        self.progress.pack(side=tk.RIGHT, padx=5)
        
        # 配置网格权重
        main_frame.columnconfigure(1, weight=1)
        main_frame.columnconfigure(2, weight=1)
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
        main_frame.rowconfigure(9, weight=1)
        
    def log_message(self, msg, level="INFO"):
        """在日志框中显示消息"""
        if self.check1.get() == 1:
            self.text7.config(state='normal')
            
            # 添加时间戳
            timestamp = time.strftime("%H:%M:%S")
            
            # 根据级别设置颜色
            tag = None
            if "错误" in msg or "失败" in msg:
                tag = "error"
            elif "警告" in msg:
                tag = "warning"
            elif "完成" in msg or "成功" in msg:
                tag = "success"
            
            # 配置标签颜色
            self.text7.tag_config("error", foreground="red")
            self.text7.tag_config("warning", foreground="orange")
            self.text7.tag_config("success", foreground="green")
            
            # 插入消息
            line = f"[{timestamp}] {msg}\n"
            if tag:
                self.text7.insert(tk.END, line, tag)
            else:
                self.text7.insert(tk.END, line)
            
            if self.chk_auto_scroll.get() == 1:
                self.text7.see(tk.END)
            
            self.text7.config(state='disabled')
            self.root.update()
    
    def update_status(self, text, color="green"):
        """更新状态栏"""
        self.status_label.config(text=text, foreground=color)
        self.root.update()
    
    def check1_click(self):
        """复选框点击事件"""
        if self.check1.get() == 1:
            self.text7.grid()
        else:
            self.text7.grid_remove()
    
    # ============ 程序启动函数 ============
    def command1_click(self):
        """启动程序1"""
        program = self.text1.get().strip()
        if program:
            try:
                subprocess.Popen(program, shell=True)
                self.log_message(f"启动程序1: {program}")
                self.update_status("程序1已启动", "green")
            except Exception as e:
                self.log_message(f"启动程序1失败: {e}", "错误")
                self.update_status("启动失败", "red")
        else:
            self.log_message("程序路径1为空", "警告")
    
    def command3_click(self):
        """启动程序2"""
        program = self.text2.get().strip()
        if program:
            try:
                subprocess.Popen(program, shell=True)
                self.log_message(f"启动程序2: {program}")
                self.update_status("程序2已启动", "green")
            except Exception as e:
                self.log_message(f"启动程序2失败: {e}", "错误")
                self.update_status("启动失败", "red")
        else:
            self.log_message("程序路径2为空", "警告")
    
    def command4_click(self):
        """启动程序3"""
        program = self.text5.get().strip()
        if program:
            try:
                subprocess.Popen(program, shell=True)
                self.log_message(f"启动程序3: {program}")
                self.update_status("程序3已启动", "green")
            except Exception as e:
                self.log_message(f"启动程序3失败: {e}", "错误")
                self.update_status("启动失败", "red")
        else:
            self.log_message("程序路径3为空", "警告")
    
    def command5_click(self):
        """启动程序4"""
        program = self.text6.get().strip()
        if program:
            try:
                subprocess.Popen(program, shell=True)
                self.log_message(f"启动程序4: {program}")
                self.update_status("程序4已启动", "green")
            except Exception as e:
                self.log_message(f"启动程序4失败: {e}", "错误")
                self.update_status("启动失败", "red")
        else:
            self.log_message("程序路径4为空", "警告")
    
    # ============ 鼠标操作函数 ============
    def mouse_action(self, action, x=None, y=None):
        """执行鼠标操作"""
        try:
            if action == "mouse_left":
                pyautogui.click(button='left')
                self.log_message("鼠标左键点击")
            elif action == "mouse_right":
                pyautogui.click(button='right')
                self.log_message("鼠标右键点击")
            elif action == "mouse_middle":
                pyautogui.click(button='middle')
                self.log_message("鼠标中键点击")
            elif action == "mouse_left_double":
                pyautogui.doubleClick(button='left')
                self.log_message("鼠标左键双击")
            elif action == "mouse_scroll_up":
                pyautogui.scroll(1)
                self.log_message("滚轮向上")
            elif action == "mouse_scroll_down":
                pyautogui.scroll(-1)
                self.log_message("滚轮向下")
            elif action == "mouse_move_up":
                x, y = pyautogui.position()
                pyautogui.moveTo(x, y-50)
                self.log_message("鼠标上移")
            elif action == "mouse_move_down":
                x, y = pyautogui.position()
                pyautogui.moveTo(x, y+50)
                self.log_message("鼠标下移")
            elif action == "mouse_move_left":
                x, y = pyautogui.position()
                pyautogui.moveTo(x-50, y)
                self.log_message("鼠标左移")
            elif action == "mouse_move_right":
                x, y = pyautogui.position()
                pyautogui.moveTo(x+50, y)
                self.log_message("鼠标右移")
            elif action == "mouse_click_hold":
                pyautogui.mouseDown()
                self.log_message("鼠标按下")
            elif action == "mouse_click_release":
                pyautogui.mouseUp()
                self.log_message("鼠标释放")
        except Exception as e:
            self.log_message(f"鼠标操作失败: {e}", "错误")
    
    # ============ 文本输入函数 ============
    def input_text(self, text_key):
        """输入预定义文本"""
        texts = {
            "text_hello": "hello",
            "text_world": "world",
            "text_test": "test",
            "text_123": "123",
            "text_abc": "abc",
            "text_password": "password"
        }
        if text_key in texts:
            pyautogui.write(texts[text_key])
            self.log_message(f"输入文本: {texts[text_key]}")
    
    # ============ 系统操作函数 ============
    def system_action(self, action):
        """执行系统操作"""
        try:
            if action == "sleep":
                subprocess.Popen("rundll32.exe powrprof.dll,SetSuspendState 0,1,0", shell=True)
                self.log_message("系统休眠")
            elif action == "power":
                subprocess.Popen("shutdown /s /t 1", shell=True)
                self.log_message("系统关机")
            elif action == "restart":
                subprocess.Popen("shutdown /r /t 1", shell=True)
                self.log_message("系统重启")
            elif action == "logout":
                subprocess.Popen("shutdown /l", shell=True)
                self.log_message("用户注销")
            elif action == "lock":
                keyboard.send("win+l")
                self.log_message("锁定系统")
            elif action == "switch_user":
                keyboard.send("win+l")
                self.log_message("切换用户")
        except Exception as e:
            self.log_message(f"系统操作失败: {e}", "错误")
    
    # ============ 应用程序启动函数 ============
    def launch_app(self, app_name):
        """启动应用程序"""
        apps = {
            "calc": "calc.exe",
            "notepad": "notepad.exe",
            "paint": "mspaint.exe",
            "cmd": "cmd.exe",
            "explorer": "explorer.exe",
            "taskmgr": "taskmgr.exe",
            "control": "control.exe",
            "snippingtool": "SnippingTool.exe"
        }
        if app_name in apps:
            try:
                subprocess.Popen(apps[app_name], shell=True)
                self.log_message(f"启动应用: {app_name}")
            except Exception as e:
                self.log_message(f"启动应用失败: {e}", "错误")
    
    # ============ 特殊按键函数 ============
    def special_key(self, key_name):
        """执行特殊按键"""
        special_keys = {
            "key_+": "+", "key_-": "-", "key_*": "*", "key_/": "/",
            "key_=": "=", "key_.": ".", "key_,": ",", "key_;": ";",
            "key_:": ":", "key_?": "?", "key_!": "!", "key_@": "@",
            "key_#": "#", "key_$": "$", "key_%": "%", "key_^": "^",
            "key_&": "&", "key_(": "(", "key_)": ")", "key_~": "~",
            "key_`": "`", "key_[": "[", "key_]": "]", "key_\\": "\\",
            "key_{": "{", "key_}": "}", "key_|": "|", "key_<": "<",
            "key_>": ">", "key_\"": "\"", "key_'": "'"
        }
        if key_name in special_keys:
            pyautogui.write(special_keys[key_name])
            self.log_message(f"输入特殊字符: {special_keys[key_name]}")
    
    # ============ 执行指令核心函数 ============
    def execute_instruction(self, token, delay_ms):
        """执行单个指令令牌"""
        try:
            # 1. 检查是否为程序启动指令 (0-3)
            if token in ["0", "1", "2", "3"]:
                if token == "0":
                    self.command1_click()
                elif token == "1":
                    self.command3_click()
                elif token == "2":
                    self.command4_click()
                elif token == "3":
                    self.command5_click()
                time.sleep(0.5)
                return
            
            # 2. 检查是否为单字符映射
            if token in self.char_map:
                key = self.char_map[token]
                keyboard.send(key)
                self.log_message(f"执行按键: {key}")
                time.sleep(delay_ms / 1000.0)
                return
            
            # 3. 检查是否为2位数映射
            if token in self.two_digit_map:
                key = self.two_digit_map[token]
                keyboard.send(key)
                self.log_message(f"执行按键: {key}")
                time.sleep(delay_ms / 1000.0)
                return
            
            # 4. 检查是否为3位数映射
            if token in self.three_digit_map:
                command = self.three_digit_map[token]
                
                # 鼠标操作
                if command.startswith("mouse_"):
                    self.mouse_action(command)
                    time.sleep(delay_ms / 1000.0)
                    return
                
                # 文本输入
                if command.startswith("text_"):
                    self.input_text(command)
                    time.sleep(delay_ms / 1000.0)
                    return
                
                # 系统操作
                if command in ["sleep", "power", "restart", "logout", "lock", "switch_user"]:
                    self.system_action(command)
                    time.sleep(delay_ms / 1000.0)
                    return
                
                # 应用程序
                if command in ["calc", "notepad", "paint", "cmd", "explorer", "taskmgr", "control", "snippingtool"]:
                    self.launch_app(command)
                    time.sleep(delay_ms / 1000.0)
                    return
                
                # 特殊按键
                if command.startswith("key_"):
                    self.special_key(command)
                    time.sleep(delay_ms / 1000.0)
                    return
                
                # 普通按键
                keyboard.send(command)
                self.log_message(f"执行按键: {command}")
                time.sleep(delay_ms / 1000.0)
                return
            
            # 5. 未识别的指令
            self.log_message(f"未知指令: {token}", "警告")
            
        except Exception as e:
            self.log_message(f"执行指令失败 {token}: {e}", "错误")
    
    def command2_click(self):
        """执行指令序列"""
        instruction_str = self.text4.get().strip()
        if not instruction_str:
            self.log_message("指令序列为空", "警告")
            return
        
        # 获取分隔符
        separator = self.text_separator.get().strip()
        if not separator:
            separator = "-"
        
        # 分割指令
        tokens = instruction_str.split(separator)
        tokens = [t.strip() for t in tokens if t.strip()]
        
        if not tokens:
            self.log_message("没有有效的指令", "警告")
            return
        
        # 获取延迟
        delay_str = self.text3.get().strip()
        try:
            delay_ms = int(delay_str) if delay_str else 100
        except ValueError:
            delay_ms = 100
            self.log_message(f"延迟值无效,使用默认值: {delay_ms}ms", "警告")
        
        # 获取执行次数
        repeat_str = self.text_repeat.get().strip()
        try:
            repeat_count = int(repeat_str) if repeat_str else 1
            repeat_count = max(1, min(repeat_count, 999))  # 限制范围
        except ValueError:
            repeat_count = 1
            self.log_message(f"执行次数无效,使用默认值: 1", "警告")
        
        self.log_message(f"开始执行指令序列,共 {len(tokens)} 个指令,重复 {repeat_count} 次")
        self.log_message(f"指令列表: {tokens}")
        self.update_status("执行中...", "orange")
        self.progress.start()
        
        # 在新线程中执行,避免阻塞UI
        def execute_thread():
            try:
                total_instructions = len(tokens) * repeat_count
                for rep in range(repeat_count):
                    if rep > 0:
                        self.log_message(f"--- 第 {rep+1} 次执行 ---")
                    
                    for i, token in enumerate(tokens):
                        current = rep * len(tokens) + i + 1
                        self.log_message(f"[{current}/{total_instructions}] 执行: '{token}'")
                        self.execute_instruction(token, delay_ms)
                
                self.log_message(f"✅ 指令序列执行完成!共执行 {total_instructions} 个指令")
                self.update_status("执行完成 ✅", "green")
                
            except Exception as e:
                self.log_message(f"执行过程中发生错误: {e}", "错误")
                self.update_status("执行出错 ❌", "red")
            finally:
                self.progress.stop()
        
        threading.Thread(target=execute_thread, daemon=True).start()
    
    # ============ 帮助和示例功能 ============
    def show_help(self):
        """显示帮助信息"""
        help_window = tk.Toplevel(self.root)
        help_window.title("使用帮助 - 数字执行机器人")
        help_window.geometry("800x600")
        
        # 创建带滚动条的文本框
        frame = ttk.Frame(help_window)
        frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        text_widget = scrolledtext.ScrolledText(frame, font=("Consolas", 10), wrap=tk.WORD)
        text_widget.pack(fill=tk.BOTH, expand=True)
        
        # 帮助内容
        help_text = """
╔═══════════════════════════════════════════════════════════════════════════╗
║                   数字执行机器人 v3.0 - 使用帮助                          ║
╚═══════════════════════════════════════════════════════════════════════════╝

【基本用法】
1. 在"指令序列"框中输入指令,使用分隔符(默认为 -)分隔
2. 设置延迟时间(毫秒)
3. 点击"执行指令"按钮

示例: 0-a-1-d-21-2-Z-cc-11-234-e-w

【指令类型】

一、程序启动指令 (0-3)
  0, 1, 2, 3  → 分别启动4个预设程序

二、单字符指令 (a-z, A-Z)
  小写字母:
  a=Tab   b=Enter   c=Space   d=Esc
  e=Ctrl+A  f=Ctrl+C  g=Ctrl+V
  h=Alt+Tab  i=Alt+N  j=Alt+X
  k=F1  l=F2  m=F3  n=F4  o=F5
  p=F6  q=F7  r=F8  s=F9  t=F10
  u=F11  v=F12  w=Backspace
  x=Home  y=End  z=Win

  大写字母:
  A=Delete  B=Ctrl+A  C=Ctrl+C  D=Ctrl+V
  E=Shift  F=Alt  G=Win+D  H=Win+E
  I=Win+M  J=Shift+Tab  K=Ctrl+Tab
  L=Ctrl+F11  M=Ctrl+O  N=Alt+F4
  O=Alt+Space  P=Ctrl+Esc  Q=Ctrl+Alt+Delete
  R=Shift+Delete  S=Ctrl+S  T=Shift+F10
  U=Ctrl+F4  V=Alt  W=Shift+F10
  X=Ctrl+Z  Y=Ctrl+Y  Z=Ctrl+F11

三、2位数指令 (00-99)
  00-09: Ctrl+数字
  10-19: Alt+数字
  20-29: Shift+数字
  30-39: Win+数字
  40-49: Ctrl+Shift+数字
  50-59: Alt+Shift+数字
  60-69: Ctrl+Alt+数字
  70-79: F1-F10
  80-89: 方向键 (上/下/左/右/PageUp/PageDown/Home/End/Insert/Delete)
  90-99: 多媒体键 (音量/播放/截图等)

四、3位数指令 (000-999)
  100-111: 鼠标操作
   100=左键  101=右键  102=中键  103=左键双击
   104=滚轮上  105=滚轮下  106-109=鼠标移动
   110=鼠标按下  111=鼠标释放

  200-213: 键盘组合键 (Ctrl/Alt/Shift/Win组合)

  300-313: 文本操作
   300=全选  301=复制  302=粘贴  303=剪切
   304=撤销  305=重做  306=查找  307=替换
   308=保存  309=打开  310=新建  311=打印
   312=关闭  313=任务管理器

  400-415: 系统操作
   400=显示桌面  401=文件资源管理器  402=运行
   403=最小化所有  404=还原所有  405=锁定电脑
   406=投影设置  407=设置  408=搜索
   409=快速链接菜单  410=关闭窗口  411=切换窗口
   412=安全选项  413=任务管理器  414=任务视图
   415=窗口菜单

  500-529: 组合键 (Ctrl+Alt/Ctrl+Shift/Alt+Shift+数字)

  600-605: 系统功能
   600=休眠  601=关机  602=重启
   603=注销  604=锁定  605=切换用户

  700-707: 应用程序
   700=计算器  701=记事本  702=画图
   703=命令提示符  704=资源管理器  705=任务管理器
   706=控制面板  707=截图工具

  800-805: 文本输入
   800=hello  801=world  802=test
   803=123  804=abc  805=password

  900-930: 特殊字符
   900=+  901=-  902=*  903=/
   904==  905=.  906=,  907=;
   908=:  909=?  910=!  911=@
   912=#  913=$  914=%  915=^
   916=&  917=(  918=)  919=~
   920=`  921=[  922=]  923=\\
   924={  925=}  926=|  927=<
   928=>  929="  930='

【高级功能】
- 重复执行: 设置"执行次数"可重复执行整个指令序列
- 自定义分隔符: 可使用任意字符作为分隔符(默认 -)
- 程序路径: 可预设4个程序路径,通过 0-3 快速启动

【注意事项】
1. 执行系统操作(关机/重启等)前请保存工作
2. 鼠标操作会控制实际鼠标,请确保能随时中断
3. 执行过程中可按 Ctrl+C 或关闭窗口中断

【示例】
0-a-1-d-21-2-Z-cc-11-234-e-w
  说明: 启动程序1 → Tab → 启动程序2 → Esc → Shift+1 → 启动程序3 
        → Ctrl+F11 → 空格 → 启动程序4 → Alt+1 → Ctrl+Alt+2 → 全选 → Win

100-200-300
  说明: 鼠标左键 → Ctrl → 全选

400-401-402
  说明: 显示桌面 → 文件资源管理器 → 运行
"""
        
        text_widget.insert(tk.END, help_text)
        text_widget.config(state='disabled')
    
    def show_examples(self):
        """显示使用示例"""
        examples = [
            ("基本示例", "0-a-1-d-21-2-Z-cc-11-234-e-w"),
            ("鼠标操作", "100-101-102-103-104-105"),
            ("系统操作", "400-401-402-403-404"),
            ("文本操作", "300-301-302-303-304-305"),
            ("组合键", "200-204-205-206"),
            ("多媒体", "90-91-92-93-94-95-96"),
            ("特殊字符", "900-901-902-903-904-905"),
            ("综合示例", "0-100-200-300-400-500-600-700-800")
        ]
        
        # 创建示例选择对话框
        example_window = tk.Toplevel(self.root)
        example_window.title("指令示例")
        example_window.geometry("500x400")
        
        frame = ttk.Frame(example_window, padding="10")
        frame.pack(fill=tk.BOTH, expand=True)
        
        ttk.Label(frame, text="选择示例指令:", font=("Arial", 12, "bold")).pack(pady=(0, 10))
        
        # 示例列表
        listbox = tk.Listbox(frame, height=12, font=("Consolas", 10))
        listbox.pack(fill=tk.BOTH, expand=True, pady=(0, 10))
        
        for name, cmd in examples:
            listbox.insert(tk.END, f"{name}: {cmd}")
        
        # 按钮框架
        btn_frame = ttk.Frame(frame)
        btn_frame.pack(fill=tk.X)
        
        def apply_example():
            selection = listbox.curselection()
            if selection:
                idx = selection[0]
                name, cmd = examples[idx]
                self.text4.delete(0, tk.END)
                self.text4.insert(0, cmd)
                self.log_message(f"应用示例: {name}")
                example_window.destroy()
            else:
                messagebox.showwarning("提示", "请先选择一个示例")
        
        ttk.Button(btn_frame, text="应用示例", command=apply_example).pack(side=tk.LEFT, padx=5)
        ttk.Button(btn_frame, text="关闭", command=example_window.destroy).pack(side=tk.RIGHT, padx=5)
    
    def reset_all(self):
        """重置所有设置"""
        self.text1.delete(0, tk.END)
        self.text2.delete(0, tk.END)
        self.text5.delete(0, tk.END)
        self.text6.delete(0, tk.END)
        self.text4.delete(0, tk.END)
        self.text3.delete(0, tk.END)
        self.text3.insert(0, "100")
        self.text_repeat.delete(0, tk.END)
        self.text_repeat.insert(0, "1")
        self.text_separator.delete(0, tk.END)
        self.text_separator.insert(0, "-")
        self.log_message("已重置所有设置")
        self.update_status("已重置", "blue")
    
    def clear_log(self):
        """清空日志"""
        self.text7.config(state='normal')
        self.text7.delete(1.0, tk.END)
        self.text7.config(state='disabled')
        self.log_message("日志已清空")

if __name__ == "__main__":
    root = tk.Tk()
    app = DigitalExecutorApp(root)
    root.mainloop()

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐