You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
8.0 KiB
214 lines
8.0 KiB
#启动exe 文件 |
|
import os |
|
import subprocess |
|
import time |
|
import uiautomation as auto |
|
from utils.config import cfg |
|
# exe_path = cfg('exe.small_exe', None) |
|
# if exe_path is None: |
|
# print(f"错误:exe_path 未配置") |
|
# exit(1) |
|
|
|
def start_exe(data): |
|
exe_path = None |
|
if "small" in data: |
|
exe_path = cfg('exe.small_exe', None) |
|
elif "big" in data: |
|
exe_path = cfg('exe.big_exe', None) |
|
else: |
|
print(f"错误:机型类型未配置") |
|
exit(1) |
|
try: |
|
# 检查文件是否存在 |
|
if not os.path.exists(exe_path): |
|
print(f"错误:切片软件路径文件不存在 - {exe_path}") |
|
return False |
|
|
|
# 检查是否是文件(不是目录) |
|
if not os.path.isfile(exe_path): |
|
print(f"错误:路径不是文件 - {exe_path}") |
|
return False |
|
|
|
# 获取 exe 文件所在的目录(工作目录) |
|
exe_dir = os.path.dirname(exe_path) |
|
print(f"工作目录设置为: {exe_dir}") |
|
|
|
# 检查工作目录是否存在 |
|
if not os.path.exists(exe_dir): |
|
print(f"错误:工作目录不存在 - {exe_dir}") |
|
return False |
|
|
|
# 使用 subprocess 启动,并设置工作目录 |
|
# 这样可以确保程序能找到同目录下的配置文件 |
|
try: |
|
process = subprocess.Popen( |
|
[exe_path], |
|
cwd=exe_dir, # 设置工作目录为 exe 所在目录 |
|
creationflags=subprocess.CREATE_NEW_CONSOLE # 在新控制台窗口运行 |
|
) |
|
print(f"✓ 成功启动程序: {exe_path}") |
|
print(f" 进程ID: {process.pid}") |
|
print(f" 工作目录: {exe_dir}") |
|
return True |
|
except Exception as e: |
|
print(f"subprocess 启动失败: {e}") |
|
# 备用方案:使用 os.startfile(但无法设置工作目录) |
|
try: |
|
# 先切换到工作目录 |
|
original_cwd = os.getcwd() |
|
os.chdir(exe_dir) |
|
os.startfile(exe_path) |
|
os.chdir(original_cwd) # 恢复原目录 |
|
print(f"✓ 使用 os.startfile 成功启动程序: {exe_path}") |
|
return True |
|
except Exception as e2: |
|
print(f"os.startfile 启动也失败: {e2}") |
|
return False |
|
|
|
except Exception as e: |
|
print(f"启动程序时发生异常: {e}") |
|
import traceback |
|
traceback.print_exc() |
|
return False |
|
|
|
|
|
def click_confirm(): |
|
""" |
|
触发点击 ESC 键,用于关闭弹框 |
|
""" |
|
try: |
|
# 发送 ESC 键到当前活动窗口 |
|
auto.SendKeys('{ESC}') |
|
print("✓ 已发送 ESC 键") |
|
time.sleep(0.3) |
|
return True |
|
except Exception as e: |
|
print(f"发送 ESC 键失败: {e}") |
|
return False |
|
|
|
|
|
def close(): |
|
""" |
|
关闭打开的应用程序 |
|
通过查找窗口名称并关闭窗口,使用多种方法确保成功 |
|
""" |
|
try: |
|
import win32gui |
|
import win32con |
|
import win32api |
|
import win32process |
|
|
|
# 应用程序的窗口名称 |
|
window_name = "赛纳3D打印控制系统 V1.4.3.2" |
|
|
|
print(f"正在查找窗口: {window_name}") |
|
|
|
# 方法1: 使用 win32gui 查找窗口(更可靠) |
|
hwnd = win32gui.FindWindow(None, window_name) |
|
|
|
if hwnd: |
|
print(f"✓ 找到窗口句柄: {hwnd}") |
|
# 激活窗口 |
|
win32gui.SetForegroundWindow(hwnd) |
|
win32gui.ShowWindow(hwnd, win32con.SW_RESTORE) # 确保窗口不是最小化 |
|
time.sleep(0.3) |
|
|
|
# 方法1: 使用 SendMessage 发送 WM_CLOSE(比 PostMessage 更强制) |
|
try: |
|
win32gui.SendMessage(hwnd, win32con.WM_CLOSE, 0, 0) |
|
print("✓ 使用 SendMessage(WM_CLOSE) 关闭窗口") |
|
time.sleep(1) |
|
# 检查窗口是否还存在 |
|
if not win32gui.IsWindow(hwnd): |
|
print("✓ 窗口已成功关闭") |
|
return True |
|
except Exception as e: |
|
print(f"SendMessage(WM_CLOSE) 失败: {e}") |
|
|
|
# 方法2: 使用 win32api 发送 Alt+F4 按键事件(更可靠) |
|
try: |
|
win32gui.SetForegroundWindow(hwnd) |
|
time.sleep(0.2) |
|
# 按下 Alt |
|
win32api.keybd_event(win32con.VK_MENU, 0, 0, 0) |
|
time.sleep(0.05) |
|
# 按下 F4 |
|
win32api.keybd_event(win32con.VK_F4, 0, 0, 0) |
|
time.sleep(0.05) |
|
# 释放 F4 |
|
win32api.keybd_event(win32con.VK_F4, 0, win32con.KEYEVENTF_KEYUP, 0) |
|
time.sleep(0.05) |
|
# 释放 Alt |
|
win32api.keybd_event(win32con.VK_MENU, 0, win32con.KEYEVENTF_KEYUP, 0) |
|
print("✓ 使用 win32api 发送 Alt+F4") |
|
time.sleep(1) |
|
# 检查窗口是否还存在 |
|
if not win32gui.IsWindow(hwnd): |
|
print("✓ 窗口已成功关闭") |
|
return True |
|
except Exception as e: |
|
print(f"win32api Alt+F4 失败: {e}") |
|
|
|
# 方法3: 尝试使用 uiautomation 的 Close() |
|
try: |
|
window = auto.WindowControl(searchDepth=1, Name=window_name) |
|
if window.Exists(0, 0): |
|
window.SetFocus() |
|
time.sleep(0.2) |
|
window.Close() |
|
print("✓ 使用 uiautomation Close() 关闭窗口") |
|
time.sleep(1) |
|
if not win32gui.IsWindow(hwnd): |
|
print("✓ 窗口已成功关闭") |
|
return True |
|
except Exception as e: |
|
print(f"uiautomation Close() 失败: {e}") |
|
|
|
# 方法4: 如果以上都失败,尝试终止进程(最后手段) |
|
print("尝试通过进程ID终止程序...") |
|
try: |
|
import psutil |
|
# 通过窗口句柄获取进程ID |
|
_, pid = win32process.GetWindowThreadProcessId(hwnd) |
|
process = psutil.Process(pid) |
|
process.terminate() |
|
print(f"✓ 已终止进程 (PID: {pid})") |
|
time.sleep(0.5) |
|
return True |
|
except ImportError: |
|
print("psutil 未安装,无法使用进程终止方式") |
|
except Exception as e: |
|
print(f"终止进程失败: {e}") |
|
|
|
print("✗ 所有关闭方法都失败了") |
|
return False |
|
else: |
|
# 如果 win32gui 找不到,尝试使用 uiautomation |
|
print("win32gui 未找到窗口,尝试使用 uiautomation...") |
|
window = auto.WindowControl(searchDepth=1, Name=window_name) |
|
if window.Exists(0, 0): |
|
print(f"✓ 使用 uiautomation 找到窗口") |
|
window.SetFocus() |
|
time.sleep(0.2) |
|
hwnd = window.Handle |
|
win32gui.SendMessage(hwnd, win32con.WM_CLOSE, 0, 0) |
|
print("✓ 使用 SendMessage(WM_CLOSE) 关闭窗口") |
|
time.sleep(1) |
|
return True |
|
else: |
|
print(f"✗ 未找到窗口: {window_name}") |
|
return False |
|
|
|
except Exception as e: |
|
print(f"关闭应用程序时发生异常: {e}") |
|
import traceback |
|
traceback.print_exc() |
|
return False |
|
|
|
#if __name__ == "__main__": |
|
# start_exe() |
|
# #启动成功之后,有一个弹框 的窗口,点击确定 |
|
# time.sleep(5) |
|
# click_confirm() |
|
# time.sleep(10) |
|
# close() |