Python中使用pyinstaller打包exe,运行时反复打开自己如何解决?

import welc

class MyWindow(QMainWindow, Ui_MainWindow): def init(self, parent=None): super(MyWindow, self).init(parent) self.setupUi(self) with open(‘qss.qss’, ‘r’) as q: self.setStyleSheet(q.read()) self.open.clicked.connect(lambda:self.aa(1))

def aa(self, ss):
    p = Process(target=welc.mo)
    p.start()

if name == ‘main’: app = QApplication(sys.argv) m = MyWindow() m.show() sys.exit(app.exec_())

这是 pyqt5 做的 gui。 使用 pyinstaller 打包 exe。

在开发环境中运行是正常的。

但是打包成 exe 后,在点 open 按钮,它只是反复打开自己(就是 m.show()这的主窗口。)

而不是打开进程中的方法。

这是什么原因?


Python中使用pyinstaller打包exe,运行时反复打开自己如何解决?

4 回复

我 打 开 我 自 己


这个问题是典型的“递归执行”或“自启动”问题。根本原因是打包时没有正确排除或处理脚本自身,导致程序运行时又触发了启动自身的命令。

最常见的情况是:你的代码里用了 os.system()subprocess.run() 或类似的命令来执行某个东西,但路径没写对。比如你想打开一个同目录下的 config.ini,但写成了当前脚本的名字,或者用了 sys.argv[0] 但打包后它指向了可执行文件自身。

核心解决思路: 确保你的代码在执行外部命令或打开文件时,绝对不要指向打包后的 .exe 文件本身

给你一个具体例子和修复方法。假设你原来的问题代码是这样的:

import subprocess
import sys
import os

def main():
    # 假设你想打开一个同目录的文本文件
    file_to_open = "notes.txt"

    # 错误做法:误用了 sys.argv[0],它指向当前exe自身!
    # 这会导致打开自己,形成循环
    subprocess.run(["notepad.exe", sys.argv[0]])

    # 正确做法:使用目标文件的明确路径
    # 方法1:如果文件就在exe旁边
    base_dir = os.path.dirname(sys.argv[0])
    target_file_path = os.path.join(base_dir, file_to_open)

    # 现在用这个明确路径去打开
    if os.path.exists(target_file_path):
        subprocess.run(["notepad.exe", target_file_path])
    else:
        print(f"文件 {target_file_path} 不存在")

if __name__ == "__main__":
    main()

关键检查点:

  1. 全局搜索你的代码,找这些关键字:os.systemsubprocessrun, call, Popen)、os.startfile
  2. 检查这些调用里第一个参数或者被操作的文件路径是不是 sys.argv[0] 或者 __file__。打包后,sys.argv[0] 就是 .exe 自己的路径。
  3. 如果你是想重启程序,那需要特殊的逻辑,比如用 sys.executable 启动一个新进程然后退出当前进程,但这和“反复打开”是两回事。

一句话总结: 检查所有执行外部命令的代码,确保参数路径没有指向打包后的可执行文件本身。

pyinstaller+process 在 Windows 下需要特殊处理。好了,搜索关键字已知了

特意登录账号前来道谢,这个问题没有关键词很难搜索,一直不知道到底是什么问题,你这个关键字很好用,非常感谢
附答案:
新版 python3
修改方式比较简单,在 if name=='main:'下添加一句 multiprocessing.freeze_support() 即可。
如下:

if name==‘main’:
# 在此处添加
multiprocessing.freeze_support()
# 这里是你的代码
# …

回到顶部