You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyInstaller编译后子进程调用辅助脚本失效,启动主程序副本

问题解决:编译后调用辅助脚本误启动主程序实例的问题

核心原因分析

PyInstaller编译后会改变程序的运行上下文,导致两个关键问题:

  • 辅助脚本编译后,原代码中sys.executable会指向主程序的EXE(而非辅助自身),触发管理员权限重启时会错误拉起主程序
  • 主程序调用辅助EXE时,若未正确获取PyInstaller临时资源目录的路径,会导致调用路径失效,最终误启动主程序

解决方案

1. 修改辅助脚本:修正管理员重启的路径指向

替换依赖sys.executable的逻辑,直接获取自身EXE的绝对路径,确保重启时拉起的是辅助程序本身:

import ctypes
import subprocess
import sys
import os

SERVICE_NAME = "dnscrypt-proxy"

def is_admin():
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False

def restart_service():
    subprocess.check_call(["sc", "stop", SERVICE_NAME], shell=True)
    subprocess.check_call(["sc", "start", SERVICE_NAME], shell=True)
    print(f"Service '{SERVICE_NAME}' restarted successfully.")

if __name__ == "__main__":
    if not is_admin():
        # 获取当前运行的辅助EXE绝对路径
        current_exe = os.path.abspath(sys.argv[0])
        # 以管理员权限重启自身
        ctypes.windll.shell32.ShellExecuteW(
            None, "runas", current_exe, "", None, 1
        )
        sys.exit()

    try:
        restart_service()
    except subprocess.CalledProcessError as e:
        print(f"Failed to restart service: {e}")
        sys.exit(1)

2. 主程序中正确获取辅助EXE的路径

主程序打包时嵌入的辅助EXE会被释放到PyInstaller的临时资源目录,需通过sys._MEIPASS获取正确路径:

import sys
import os
import subprocess

def restart_dnscrypt_service():
    # 区分开发环境与编译后环境的辅助EXE路径
    if hasattr(sys, '_MEIPASS'):
        helper_exe = os.path.join(sys._MEIPASS, "restart_service_helper.exe")
    else:
        helper_exe = os.path.join(os.path.dirname(__file__), "restart_service_helper.exe")
    
    # 启动辅助程序,不阻塞主进程
    subprocess.Popen([helper_exe], creationflags=subprocess.CREATE_NO_WINDOW)

3. 重新打包的正确命令

执行打包时确保辅助EXE的嵌入路径正确:

pyinstaller --onefile --windowed --add-binary "restart_service_helper.exe;." your_main_script.py

内容的提问来源于stack exchange,提问作者Adrian M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 05:37:44