|
|
|
@ -4,6 +4,8 @@ import subprocess |
|
|
|
import shutil |
|
|
|
import shutil |
|
|
|
import time |
|
|
|
import time |
|
|
|
import uiautomation as auto |
|
|
|
import uiautomation as auto |
|
|
|
|
|
|
|
import win32api |
|
|
|
|
|
|
|
import win32con |
|
|
|
from utils.config import cfg |
|
|
|
from utils.config import cfg |
|
|
|
# exe_path = cfg('exe.small_exe', None) |
|
|
|
# exe_path = cfg('exe.small_exe', None) |
|
|
|
# if exe_path is None: |
|
|
|
# if exe_path is None: |
|
|
|
@ -48,32 +50,64 @@ def start_exe(data): |
|
|
|
if not os.path.exists(data_dir): |
|
|
|
if not os.path.exists(data_dir): |
|
|
|
os.makedirs(data_dir) |
|
|
|
os.makedirs(data_dir) |
|
|
|
|
|
|
|
|
|
|
|
# 使用 subprocess 启动,并设置工作目录 |
|
|
|
# 使用 win32api.ShellExecute 完全模拟双击启动 |
|
|
|
# 这样可以确保程序能找到同目录下的配置文件 |
|
|
|
# ShellExecute 是 Windows 系统双击文件时调用的 API,行为最接近真实双击 |
|
|
|
try: |
|
|
|
try: |
|
|
|
process = subprocess.Popen( |
|
|
|
# 先切换到工作目录(ShellExecute 会使用当前工作目录) |
|
|
|
[exe_path], |
|
|
|
original_cwd = os.getcwd() |
|
|
|
cwd=exe_dir, # 设置工作目录为 exe 所在目录 |
|
|
|
os.chdir(exe_dir) |
|
|
|
creationflags=subprocess.CREATE_NEW_CONSOLE # 在新控制台窗口运行 |
|
|
|
|
|
|
|
|
|
|
|
# ShellExecute(hwnd, operation, file, parameters, directory, showCmd) |
|
|
|
|
|
|
|
# operation: "open" 表示打开文件(模拟双击) |
|
|
|
|
|
|
|
# showCmd: SW_SHOWNORMAL (1) 表示正常显示窗口 |
|
|
|
|
|
|
|
result = win32api.ShellExecute( |
|
|
|
|
|
|
|
0, # hwnd: 父窗口句柄,0 表示桌面 |
|
|
|
|
|
|
|
"open", # operation: 打开文件 |
|
|
|
|
|
|
|
exe_path, # file: 要执行的文件路径 |
|
|
|
|
|
|
|
"", # parameters: 命令行参数(空字符串表示无参数) |
|
|
|
|
|
|
|
exe_dir, # directory: 工作目录 |
|
|
|
|
|
|
|
win32con.SW_SHOWNORMAL # showCmd: 正常显示窗口 |
|
|
|
) |
|
|
|
) |
|
|
|
print(f"✓ 成功启动程序: {exe_path}") |
|
|
|
|
|
|
|
print(f" 进程ID: {process.pid}") |
|
|
|
# 恢复原目录 |
|
|
|
print(f" 工作目录: {exe_dir}") |
|
|
|
os.chdir(original_cwd) |
|
|
|
return True |
|
|
|
|
|
|
|
|
|
|
|
# ShellExecute 返回值 > 32 表示成功 |
|
|
|
|
|
|
|
if result > 32: |
|
|
|
|
|
|
|
print(f"✓ 成功启动程序(模拟双击): {exe_path}") |
|
|
|
|
|
|
|
print(f" 工作目录: {exe_dir}") |
|
|
|
|
|
|
|
print(f" 返回值: {result}") |
|
|
|
|
|
|
|
return True |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
print(f"✗ ShellExecute 启动失败,返回值: {result}") |
|
|
|
|
|
|
|
# 如果 ShellExecute 失败,尝试备用方案 |
|
|
|
|
|
|
|
raise Exception(f"ShellExecute 返回错误代码: {result}") |
|
|
|
|
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
except Exception as e: |
|
|
|
print(f"subprocess 启动失败: {e}") |
|
|
|
print(f"ShellExecute 启动失败: {e}") |
|
|
|
# 备用方案:使用 os.startfile(但无法设置工作目录) |
|
|
|
# 备用方案1:使用 os.startfile(也使用 ShellExecute,但无法设置工作目录) |
|
|
|
try: |
|
|
|
try: |
|
|
|
# 先切换到工作目录 |
|
|
|
|
|
|
|
original_cwd = os.getcwd() |
|
|
|
original_cwd = os.getcwd() |
|
|
|
os.chdir(exe_dir) |
|
|
|
os.chdir(exe_dir) |
|
|
|
os.startfile(exe_path) |
|
|
|
os.startfile(exe_path) |
|
|
|
os.chdir(original_cwd) # 恢复原目录 |
|
|
|
os.chdir(original_cwd) |
|
|
|
print(f"✓ 使用 os.startfile 成功启动程序: {exe_path}") |
|
|
|
print(f"✓ 使用 os.startfile 成功启动程序: {exe_path}") |
|
|
|
return True |
|
|
|
return True |
|
|
|
except Exception as e2: |
|
|
|
except Exception as e2: |
|
|
|
print(f"os.startfile 启动也失败: {e2}") |
|
|
|
print(f"os.startfile 启动也失败: {e2}") |
|
|
|
return False |
|
|
|
# 备用方案2:使用 subprocess(最后手段) |
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
process = subprocess.Popen( |
|
|
|
|
|
|
|
[exe_path], |
|
|
|
|
|
|
|
cwd=exe_dir, |
|
|
|
|
|
|
|
creationflags=subprocess.CREATE_NEW_CONSOLE |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
print(f"✓ 使用 subprocess 成功启动程序: {exe_path}") |
|
|
|
|
|
|
|
print(f" 进程ID: {process.pid}") |
|
|
|
|
|
|
|
return True |
|
|
|
|
|
|
|
except Exception as e3: |
|
|
|
|
|
|
|
print(f"subprocess 启动也失败: {e3}") |
|
|
|
|
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
except Exception as e: |
|
|
|
print(f"启动程序时发生异常: {e}") |
|
|
|
print(f"启动程序时发生异常: {e}") |
|
|
|
|