将Crypter打包为可执行文件时PyInstaller调用失败问题
PyInstaller调用失败导致Crypter项目打包异常
问题背景
尝试将GitHub上的Crypter项目用PyInstaller打包为可执行文件,点击Build后在调用PyInstaller环节失败。但直接执行python Builder.pyw运行脚本完全正常;系统命令行执行pyinstaller --version能返回指定的3.6版本,运行脚本时已使用对应requirements.txt的虚拟环境,Python版本为3.7.0。
相关代码
def __run_pyinstaller(self, spec_path): ''' 功能:调用PyInstaller处理生成的SPEC文件 参数spec_path:已创建的PyInstaller SPEC文件路径 ''' # 检查是否停止 if self.__stop_event.isSet(): raise UserHalt self.__console_log(msg="正在调用PyInstaller,请稍候...") # 获取PyInstaller路径 pyinstaller_path = os.path.join(os.path.dirname(sys.executable), "pyinstaller.exe") if not os.path.isfile(pyinstaller_path): self.__console_log(f"在路径'{pyinstaller_path}'未找到PyInstaller,将尝试调用系统全局版本", debug_level=2) pyinstaller_path = "pyinstaller" else: self.__console_log(f"在路径'{pyinstaller_path}'找到PyInstaller", debug_level=2) # 构建命令 cmd = [ pyinstaller_path, '--noconsole', '--clean', '-F', ] if self.user_input_dict["upx_dir"]: cmd.append("--upx-dir") cmd.append(self.user_input_dict["upx_dir"]) else: cmd.append("--noupx") cmd.append(spec_path) self.__console_log(msg="执行命令:%s" % " ".join(cmd), debug_level=2) # 调用PyInstaller子进程 try: build = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, creationflags=0x08000000 # 阻止控制台窗口弹出 ) except WindowsError as we: raise BuildFailure( ERROR_FILE_NOT_FOUND, "调用PyInstaller失败,请确认PyInstaller已安装且可在系统路径中找到" ) while True: # 检查是否停止 if self.__stop_event.isSet(): build.kill() raise UserHalt line = build.stdout.readline() if line: self.__console_log(msg=line.rstrip(), _class="PyInstaller", debug_level=1) else: break
程序控制台日志
[2024-06-02 13:29:52]: 构建已启动 [2024-06-02 13:29:52]: 调试级别:1 - 低级 [2024-06-02 13:29:52]: 构建器:正在检查配置... [2024-06-02 13:29:52]: 构建器:检查builder_language [2024-06-02 13:29:53]: 构建器:检查pyinstaller_aes_key [2024-06-02 13:29:53]: 构建器:检查icon_file [2024-06-02 13:29:53]: 构建器:检查open_gui_on_login [2024-06-02 13:29:53]: 构建器:检查time_delay [2024-06-02 13:29:53]: 构建器:检查gui_title [2024-06-02 13:29:53]: 构建器:检查upx_dir [2024-06-02 13:29:53]: 构建器:检查delete_shadow_copies [2024-06-02 13:29:53]: 构建器:检查disable_task_manager [2024-06-02 13:29:53]: 构建器:检查key_destruction_time [2024-06-02 13:29:54]: 构建器:检查wallet_address [2024-06-02 13:29:54]: 构建器:检查bitcoin_fee [2024-06-02 13:29:54]: 构建器:检查encrypt_attached_drives [2024-06-02 13:29:54]: 构建器:检查encrypt_user_home [2024-06-02 13:29:54]: 构建器:检查max_file_size_to_encrypt [2024-06-02 13:29:54]: 构建器:检查filetypes_to_encrypt [2024-06-02 13:29:54]: 构建器:检查encrypted_file_extension [2024-06-02 13:29:54]: 构建器:检查make_gui_resizeable [2024-06-02 13:29:54]: 构建器:检查always_on_top [2024-06-02 13:29:55]: 构建器:检查background_colour [2024-06-02 13:29:55]: 构建器:检查heading_font_colour [2024-06-02 13:29:55]: 构建器:检查primary_font_colour [2024-06-02 13:29:55]: 构建器:检查secondary_font_colour [2024-06-02 13:29:55]: 构建器:检查ransom_message [2024-06-02 13:29:55]: 构建器:检查debug_level [2024-06-02 13:29:55]: 构建器:验证成功 [2024-06-02 13:29:55]: 构建器:加密将针对已挂载驱动器和用户主目录 [2024-06-02 13:29:55]: 构建器:在../CrypterBuilder\Resources\runtime.cfg创建二进制运行时配置 [2024-06-02 13:29:55]: 构建器:运行时配置写入成功 [2024-06-02 13:29:55]: 构建器:创建PyInstaller SPEC文件 [2024-06-02 13:29:55]: 构建器:(警告)未指定UPX路径,PyInstaller生成的二进制文件将不会被压缩。建议使用UPX,可将文件大小减少数MB [2024-06-02 13:29:55]: 构建器:SPEC文件创建成功 [2024-06-02 13:29:55]: 构建器:正在调用PyInstaller,请稍候... [2024-06-02 13:29:55]: (错误):构建器:构建失败(错误码2):调用PyInstaller失败,请确认PyInstaller已安装且可在系统路径中找到 [2024-06-02 13:29:55]: 构建结束,出现错误
移除异常处理后的报错信息
Exception in thread Thread-1: Traceback (most recent call last): File "threading.py", line 917, in _bootstrap_inner File "CrypterBuilder\BuilderThread.py", line 192, in run File "CrypterBuilder\BuilderThread.py", line 306, in __run_pyinstaller File "subprocess.py", line 756, in __init__ File "subprocess.py", line 1155, in _execute_child FileNotFoundError: [WinError 2] 系统找不到指定的文件
解决思路
- 修正虚拟环境中PyInstaller路径:脚本默认在Python可执行文件同级目录查找
pyinstaller.exe,但虚拟环境中PyInstaller实际位于Scripts子目录,修改路径拼接逻辑:# 替换原路径获取代码 pyinstaller_path = os.path.join(os.path.dirname(sys.executable), "Scripts", "pyinstaller.exe") - 显式指定PyInstaller完整路径:激活虚拟环境后执行
where pyinstaller获取实际路径,在脚本中硬编码该路径测试。 - 修改subprocess调用参数:使用
pyinstaller命令时添加shell=True,让系统通过shell查找命令路径(仅Windows环境适用):build = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, creationflags=0x08000000, shell=True ) - 确认虚拟环境激活状态:在脚本开头添加
print(sys.executable),输出当前Python路径,验证是否处于目标虚拟环境中。
内容的提问来源于stack exchange,提问作者Hoko L
相关产品推荐
相关产品推荐

