Windows 快速启动器
在日常工作和学习中,我们经常需要快速访问某些功能或资源,例如打开常用网站、启动应用程序或执行特定命令。Linux 用户可以通过 alias 快速实现这些操作,但在 Windows 上缺乏类似的原生支持。本文将介绍如何使用 Python 开发一个 隐藏式文本输入框程序,模拟 Linux 的 alias 功能,实现快速启动和访问。
功能概述
该程序的核心功能如下:
-
隐藏式界面:默认情况下,程序界面隐藏,按下热键后显示。
-
快速输入:通过键盘输入关键字,按下回车键后执行相应操作。
-
自定义映射:通过配置文件(如
store.txt)定义关键字与操作的映射关系。 -
快速打开网站:输入关键字后,自动打开对应的 URL。
-
打开文件夹:输入关键字后,打开指定的文件夹。
-
启动应用程序:输入关键字后,启动指定的应用程序。
-
执行系统命令:输入关键字后,执行系统命令(如打开服务管理器)。
-
单实例运行:确保程序只运行一个实例,避免重复启动。
实现原理
1. 隐藏式界面
使用 tkinter 创建一个无标题栏的文本输入框界面,默认隐藏。通过全局热键(如 Alt + Win + Z)显示界面,并将焦点设置到输入框。
2. 关键字映射
通过读取配置文件(如 store.txt),将关键字与操作(如 URL、文件夹路径、应用程序路径或系统命令)关联起来。例如:
3. 快速执行
输入关键字后,按下回车键,程序会根据配置文件执行相应操作(如打开浏览器访问 URL、打开文件夹、启动应用程序或执行系统命令)。
4. 单实例运行
使用 psutil 检查程序是否已经运行,避免重复启动。
代码实现
以下是完整的 Python 代码:
import tkinter as tk import keyboard import ctypes import sys import os import psutil import webbrowser import subprocess import time class StoreItem: def __init__(self, keyword, content, type_): self.keyword = keyword self.content = content self.type_ = type_ class Store: def __init__(self, file_path): self.file_path = file_path self.items = {} self.last_modified = 0 self.load() def load(self): if not os.path.exists(self.file_path): print(f"错误:未找到文件 {self.file_path},请确保 store.txt 和脚本在同一目录下。") return self.last_modified = os.path.getmtime(self.file_path) self.items.clear() with open(self.file_path, "r", encoding="utf-8") as file: for line in file: columns = line.strip().split() if len(columns) == 3: keyword, content, type_ = columns self.items[keyword] = StoreItem(keyword, content, type_) def get_item(self, keyword): if os.path.getmtime(self.file_path) > self.last_modified: self.load() return self.items.get(keyword) def is_already_running(): current_pid = os.getpid() for proc in psutil.process_iter(['pid', 'name']): try: if proc.info['name'] == os.path.basename(sys.argv[0]) and proc.info['pid'] != current_pid: return True except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): pass return False if is_already_running(): print("程序已经在运行中,退出当前实例。") sys.exit(0) user32 = ctypes.windll.user32 imm32 = ctypes.windll.imm32 def show_window(): if not root.winfo_viewable(): root.deiconify() root.lift() root.focus_force() screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() window_width = root.winfo_reqwidth() window_height = root.winfo_reqheight() x = screen_width - window_width - 20 y = 20 root.geometry(f"+{x}+{y}") text_entry.focus_set() text_entry.delete(0, tk.END) switch_to_english() def hide_window(): root.withdraw() def on_enter(event): input_text = text_entry.get() if input_text.strip(): ontext(input_text) text_entry.delete(0, tk.END) hide_window() def handle_action(item): if item.type_ == "u": webbrowser.open(item.content) print(f"已打开 URL: {item.content}") elif item.type_ == "f": os.startfile(item.content) print(f"已打开文件夹: {item.content}") elif item.type_ == "o": subprocess.run(item.content, shell=True) print(f"已执行命令: {item.content}") def ontext(key): item = store.get_item(key) if item: handle_action(item) else: print(f"未找到关键字为 {key} 的记录。") def switch_to_english(): hwnd = user32.GetForegroundWindow() himc = imm32.ImmGetContext(hwnd) if himc: imm32.ImmSetOpenStatus(himc, False) imm32.ImmReleaseContext(hwnd, himc) root = tk.Tk() root.overrideredirect(True) root.configure(bg="white") text_entry = tk.Entry( root, width=20, font=("Arial", 12), bd=0, highlightthickness=1, justify="left" ) text_entry.pack(padx=10, pady=10) root.withdraw() text_entry.bind("<Return>", on_enter) keyboard.add_hotkey("alt+windows+z", show_window) keyboard.add_hotkey("esc", hide_window) text_entry.bind("<FocusIn>", lambda event: switch_to_english()) script_dir = os.path.dirname(os.path.abspath(__file__)) store_path = os.path.join(script_dir, "store.txt") store = Store(store_path) root.mainloop()
配置文件示例
在 store.txt 文件中添加以下内容:
功能说明
-
打开 URL:
-
输入
google,打开https://www.google.com。 -
输入
python,打开https://www.python.org。
-
-
打开文件夹:
-
输入
ubunt,打开D:\ubunt文件夹。
-
-
启动应用程序或执行系统命令:
-
输入
services,打开服务管理器。 -
输入
notepad,启动记事本。
-
使用方法
-
将 Python 脚本和
store.txt文件放在同一目录下。 -
运行 Python 脚本。
-
按下
Alt + Win + Z显示界面,输入关键字后按Enter键。 -
程序会根据配置文件执行相应操作。
打包为可执行文件
使用 PyInstaller 将脚本打包为 Windows 可执行文件:
pyinstaller --onefile --windowed main.py
生成的 main.exe 文件位于 dist 文件夹中。
总结
通过抽象 StoreItem 和 Store 类,代码逻辑更加清晰和模块化。快速启动器 不仅支持打开网址,还能打开文件夹、启动应用程序和执行系统命令。你可以根据需要在 store.txt 中添加更多映射关系,实现快速访问常用资源的目标。希望这个工具能帮助你提高工作效率!
新修改的代码:
import tkinter as tk import keyboard # 用于监听全局热键 import ctypes # 用于切换输入法 import psutil # 用于检查进程 import sys,webbrowser, os, subprocess # 检查是否已经有相同进程在运行 def is_already_running(): current_pid = os.getpid() for proc in psutil.process_iter(['pid', 'name']): try: # 检查进程名称和当前脚本名称是否相同 if proc.info['name'] == os.path.basename(sys.argv[0]) and proc.info['pid'] != current_pid: print(os.path.basename(sys.argv[0])) os.system("pause") return True except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): pass return False # 如果已经有相同进程在运行,退出程序 if is_already_running(): print("程序已经在运行中,退出当前实例。") sys.exit(0) # 获取输入法相关的 Windows API user32 = ctypes.windll.user32 imm32 = ctypes.windll.imm32 def show_window(): # 确保窗口完全销毁后重建的问题 (针对某些Tk版本兼容性) if not root.winfo_exists(): return # 强制窗口显示并更新界面 root.deiconify() root.update_idletasks() # 关键!强制完成所有UI渲染 # 计算精确的窗口尺寸(使用实际渲染后的尺寸) window_width = root.winfo_width() window_height = root.winfo_height() # 获取屏幕有效工作区(排除任务栏) screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() # 计算右侧定位坐标(考虑多显示器情况) x = screen_width - window_width - 20 y = 20 # 应用定位(先移动窗口再置顶) root.geometry(f"+{x}+{y}") # 窗口层级和焦点控制 root.lift() # 置顶窗口 root.attributes("-topmost", True) # 强制置顶属性 root.after(100, lambda: root.attributes("-topmost", False)) # 100ms后取消置顶 # 焦点控制(多重保障) text_entry.focus_set() root.after(10, text_entry.focus_force) # 延迟强制焦点 # 清空输入框 text_entry.delete(0, tk.END) # 输入法控制(延迟执行确保焦点生效) root.after(50, switch_to_english) # 输入法切换函数增强版 def switch_to_english(): try: # 获取当前焦点窗口 hwnd = user32.GetForegroundWindow() # 获取线程输入法上下文d thread_id = user32.GetWindowThreadProcessId(hwnd, None) himc = imm32.ImmGetContext(hwnd) if himc: # 强制关闭输入法 imm32.ImmSetOpenStatus(himc, False) imm32.ImmReleaseContext(hwnd, himc) # 额外发送ESC键确保清除输入状态 keyboard.send('esc', do_press=True, do_release=True) except Exception as e: print(f"输入法切换失败: {str(e)}") # 定义隐藏窗口的函数 def hide_window(): root.withdraw() # 隐藏窗口 # 定义处理 Enter 键的函数 def on_enter(event): input_text = text_entry.get() # 获取输入框内容 if input_text.strip(): # 如果输入内容不为空 ontext(input_text) # 调用 ontext 函数并传递输入文本 text_entry.delete(0, tk.END) # 清空输入框内容 hide_window() # 隐藏窗口 def onUrl(keyword, content): url = content # 获取 URL webbrowser.open(url) # 通过浏览器打开 URL #os.startfile(url)cxycc print(f"已打开 URL: {url}") import subprocess def onObj(keyword, content): try: #subprocess.run(content, check=True) #webbrowser.open(content) #os.system(f'start "{content}"') process = subprocess.Popen(content) print(f'start "{content}"') print(f"成功打开并等待 {content} 完成") except subprocess.CalledProcessError as e: print(f"程序返回非零退出码: {e}") except FileNotFoundError: print(f"文件未找到: {content}") except Exception as e: print(f"打开文件时出错: {e}") def onKey(keyword, content, type_): if type_ == "u": onUrl(keyword, content) elif type_ == "o": onObj(keyword, content) # 定义 ontext 函数 def ontext(key): print(f"输入的文本是:{key}") # 这里可以替换为你的自定义逻辑 # 获取脚本所在目录的绝对路径 script_dir = os.path.dirname(os.path.abspath(__file__)) # 拼接 store.txt 的绝对路径 store_path = os.path.join(script_dir, "store.csv") # 检查文件是否存在 if not os.path.exists(store_path): print(f"错误:未找到文件 {store_path},请确保 store.txt 和脚本在同一目录下。") return # 打开 store.txt 文件 with open(store_path, mode='r', encoding='utf-8') as file: for line in file: # 按空格分割每行数据 columns = line.strip().split(",") if len(columns) == 3: # 确保每行有3列 keyword, content, type_ = columns print(f"{keyword}/{content}/{type_}") if keyword != key: continue onKey(keyword, content, type_) return print(f"未找到关键字为 {key} 的记录。") # 定义切换为英文输入法的函数 def switch_to_english(): # 获取当前激活窗口的句柄 hwnd = user32.GetForegroundWindow() # 获取当前线程的输入法上下文 himc = imm32.ImmGetContext(hwnd) if himc: # 设置输入法为英文 imm32.ImmSetOpenStatus(himc, False) # 关闭输入法 imm32.ImmReleaseContext(hwnd, himc) # 创建主窗口 root = tk.Tk() # 移除标题栏和边框 root.overrideredirect(True) # 设置窗口背景颜色 root.configure(bg="white") # 创建一个文本输入框 text_entry = tk.Entry( root, width=20, # 文本框长度为60 font=("Arial", 12), bd=0, highlightthickness=1, justify="left" # 文本框靠左输入 ) text_entry.pack(padx=10, pady=10) # 默认隐藏窗口 root.withdraw() # 绑定 Enter 键事件 text_entry.bind("<Return>", on_enter) try: # 绑定 Alt+Win+Z 热键 keyboard.add_hotkey("alt+win+z", show_window, suppress=True) except Exception as e: print(f"出现错误: {e}") # 绑定 Esc 键隐藏窗口 keyboard.add_hotkey("esc", hide_window) # 绑定输入框获取焦点事件 text_entry.bind("<FocusIn>", lambda event: switch_to_english()) # 运行主循环 root.mainloop()
浙公网安备 33010602011771号