跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python

Python 项目打包成 exe 并添加卸载功能教程

如何使用 PyInstaller 将 Python 脚本打包为独立的可执行文件,并利用 Inno Setup Compiler 创建具备安装向导和卸载功能的安装包。内容涵盖虚拟环境配置、GUI 程序编写规范、打包参数详解、Inno Setup 脚本定制以及常见依赖问题的解决方案,旨在帮助开发者实现软件的便捷分发与环境隔离部署。

数字游民发布于 2025/2/6更新于 2026/6/323 浏览
Python 项目打包成 exe 并添加卸载功能教程

前言

虽然很多开发者专注于 Web 开发,但对 Python 的众多开源项目一直都很关注。像 Stable Diffusion 的 AI 绘画,以及 So-VITS-SVC 音色替换等项目的源码部署文档通常比较完善。尽管如此,对于刚入门或本地环境搭建容易踩坑的同学来说,直接运行源码往往不太友好。针对这一现象,网上已有各种解决方案提供一键部署,无需安装 Python 环境,无需下载各种依赖包,点击 exe 即可使用。

那么这些方案是如何实现的呢?很多人会想到 PyInstaller。它确实可以解决整体环境的打包问题,但有时候一些图标和依赖文件需要放在一起才能正常使用,类似于绿色桌面工具。有没有方法对这个进一步封装,就是点击 exe 后需要安装,然后安装后才是项目的文件,还可以卸载?答案是使用 Inno Setup Compiler。接下来我将用一个 GUI 的小 demo 完成 exe 打包和进一步安装打包。

PyInstaller 与 Inno Setup 流程示意图

环境准备

为了确保打包过程顺利,建议准备以下环境:

  • Python 3.8 及以上版本
  • Tkinter (Python 自带 GUI 库)
  • PyInstaller 6.3.0 或更高版本
  • Inno Setup Compiler (用于制作安装包)

建议使用 Conda 创建独立的虚拟环境,避免系统全局环境冲突。

基本流程

  1. 环境创建:用 conda 单独创建一个虚拟环境,例如 tools_env。
  2. 编写代码:编写一个 tkinter 应用,为了美观,准备尺寸 32x32 和 64x64 的图标文件。
  3. PyInstaller 打包:将应用打成文件包(含 exe),生成 dist 目录。
  4. Inno Setup 打包:使用 Inno Setup Compiler 对 dist 目录进行打包,设置文件关联、图标和信息,最终生成带有安装向导和卸载功能的安装包。

完整打包流程图

开始操作

1. 环境创建

# 1. 创建环境
conda create -n tools_env python=3.8

# 2. 进入环境
conda activate tools_env

# 3. 安装 pyinstaller
pip install pyinstaller -i https://pypi.tuna.tsinghua.edu.cn/simple

2. 编码示例

以下是一个简单的批量重命名工具示例,使用了 Tkinter 构建界面。注意清理了原有的推广信息。

import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import os

class Application(tk.Tk):

    def __init__(self):
        super().__init__()
        self.title("文件批量重命名工具")
        # 确保 iconbitmap 路径正确,打包时需放入同一目录
        try:
            self.iconbitmap('logo.ico')
        except:
            pass
        
        self.geometry("600x370")  # 设置固定的窗口大小
        self.resizable(False, False)  # 禁止调整窗口大小
        self.style = ttk.Style(self)
        self.main_color = self.cget("bg")

        self.style.configure("TEntry",
                             padding=6,
                             relief="flat",
                             background="#0078d7",
                             foreground="black",
                             font=("Arial", 12, "bold"))

        self.style.configure("TLabel",
                             font=("Arial", 12, "bold"))

        self.style.configure("TButton",
                             padding=6,
                             font=("Arial", 12))

        self.create_widgets()

    def create_widgets(self):
        self.path_label = ttk.Label(self, text='绝对路径:')
        self.path_label.grid(row=0, sticky=tk.W, pady=30, padx=20)

        self.path = tk.StringVar()
        self.path_entry = ttk.Entry(self, width=60, textvariable=self.path)
        self.path_entry.grid(row=0, column=1, sticky=tk.E, pady=5)

        self.rename_label = ttk.Label(self, text='修改名称:')
        self.rename_label.grid(row=1, sticky=tk.W, pady=5, padx=20)

        self.rename = tk.StringVar()
        self.rename_entry = ttk.Entry(self, width=60, textvariable=self.rename)
        self.rename_entry.grid(row=1, column=1, sticky=tk.E, pady=5)

        self.msg_text = tk.Text(self, height=2, width=60, wrap='none')
        self.msg_text.grid(row=2, column=1, sticky=tk.W, pady=15)
        self.msg_text.configure(bd=0, relief="solid", bg=self.main_color)

        ttk.Button(self, text='确认修改', command=self.start_program).grid(row=3, column=1, sticky=tk.W, pady=20, padx=120)
        ttk.Button(self, text='关于', command=self.about).grid(row=4, column=1, sticky=tk.W, padx=120)

    def start_program(self):
        path = self.path.get()
        rename = self.rename.get()

        if path == "" or rename == "":
            messagebox.showwarning("警告", "输入框不能为空!")
            return

        if not os.path.isdir(path):
            messagebox.showwarning("警告", "绝对路径不正确!")
            return

        i = 0
        FileList = os.listdir(path)

        for files in FileList:
            oldDirPath = os.path.join(path, files)
            self.msg_text.delete(1.0, tk.END)
            self.msg_text.insert(tk.END, f"处理中:{oldDirPath}")

            if os.path.isdir(oldDirPath):
                continue  # 简化逻辑,仅处理文件

            fileName = os.path.splitext(files)[0]
            fileType = os.path.splitext(files)[1].lower()

            newDirPath = os.path.join(path, f"{rename}_{i}{fileType}")

            try:
                os.rename(oldDirPath, newDirPath)
                i += 1
            except Exception as e:
                print(f"重命名失败:{files}, 错误:{e}")

        messagebox.showinfo("信息", "操作完成!")

    def about(self):
        messagebox.showinfo("关于", "工具:批量修改文件 1.0\n作者:技术团队")

    def quit_program(self):
        self.destroy()

if __name__ == "__main__":
    app = Application()
    app.mainloop()

3. 开始打包

使用 PyInstaller 将脚本转换为可执行文件。命令如下:

pyinstaller -F -w Application.py --icon=logo.ico

参数说明:

  • --icon=图标路径:指定 exe 图标。
  • -F:打包成一个 exe 文件。
  • -w:使用窗口模式,无控制台黑框。
  • -c:使用控制台模式,有黑框。
  • -D:创建一个目录,里面包含 exe 以及其他一些依赖性文件。

如果修改了代码需要重新打包,建议删除上一次生成的 .spec 后缀文件,以免配置冲突。打包成功后,控制台会显示 Building EXE from EXE-00.toc completed successfully。根目录下的 dist 文件夹即为打包后的文件包,里面包含了 exe 及所需的动态链接库和图片等资源。

打包成功后的 dist 目录结构

dist 目录内容预览

4. Inno Setup Compiler 操作

Inno Setup 是一款免费且强大的 Windows 安装程序制作软件。我们需要编写一个脚本文件(.iss)来定义安装过程。

新建脚本

打开 Inno Setup Compiler,选择新建脚本向导,填写应用程序名称、版本号等信息。

新建脚本向导

选择主程序和文件

在文件选择步骤中,指向之前 PyInstaller 生成的 dist 文件夹中的 exe 文件,并勾选其他需要的资源文件。

选择主程序

设置名称和图标

设置安装程序的标题、公司名称以及安装图标。

设置名称和图标

导出位置

选择编译后的安装包输出路径。在生成前还可以设置协议条款等高级选项。

选择导出位置

运行脚本

点击运行按钮开始生成安装包。

生成安装包

安装效果

安装完成后,安装目录内会自带卸载程序,用户可以在'控制面板'或'设置'中轻松卸载。

安装目录与卸载程序

深入:Inno Setup 脚本详解

为了更灵活地控制安装过程,我们可以手动编辑 .iss 脚本文件。以下是标准脚本结构的详细说明:

[Setup]
AppName=My Program
AppVersion=1.0
DefaultDirName={autopf}\MyProgram
DefaultGroupName=My Program
OutputDir=output
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes
WizardStyle=modern

[Files]
Source: "dist\*.exe"; DestDir: "{app}"
Source: "dist\*.dll"; DestDir: "{app}"
Source: "images\*.*"; DestDir: "{app}\images"

[Icons]
Name: "{group}\{cm:UninstallProgram,MyProgram}"; Filename: "{uninstallexe}"
Name: "{autodesktop}\MyProgram"; Filename: "{app}\myprogram.exe"

[Run]
Filename: "{app}\myprogram.exe"; Description: "{cm:LaunchProgram,MyProgram}"; Flags: nowait postinstall skipifsilent
  • [Setup]:定义安装程序的基本属性,如应用名、版本、默认安装目录 {app} 代表用户选择的目录,{autopf} 代表 Program Files。
  • [Files]:指定要复制的文件。Source 是源路径,DestDir 是目标路径。支持通配符。
  • [Icons]:创建快捷方式。{group} 代表开始菜单组,{autodesktop} 代表桌面。
  • [Run]:安装完成后自动运行的程序。nowait 表示不等待程序结束,postinstall 表示在安装结束时运行。

常见问题与解决方案

1. 缺少 DLL 报错

如果在运行 exe 时提示缺少 MSVCP140.dll 等文件,说明缺少 Visual C++ 运行库。解决方法是在 PyInstaller 打包时添加 --add-data 参数引入必要的 DLL,或者在 Inno Setup 脚本中添加 VC++ 运行库的安装逻辑。

2. 杀毒软件误报

由于未签名的 exe 容易被杀毒软件拦截。建议申请代码签名证书(Authenticode)对 exe 进行签名,或者在发布前告知用户添加信任白名单。

3. 打包体积过大

PyInstaller 默认会将所有依赖打包进去。可以使用 --onefile 优化,或者检查是否有不必要的模块被引入。对于大型项目,考虑使用 --onedir 模式,体积会更小且加载更快。

4. 中文乱码

确保源代码文件保存为 UTF-8 格式。在 PyInstaller 打包时,如果遇到中文路径问题,可以尝试在脚本开头添加 # -*- coding: utf-8 -*-。

总结

通过结合 PyInstaller 和 Inno Setup Compiler,开发者可以将 Python 项目转化为专业的 Windows 应用程序。这不仅解决了环境依赖问题,还提升了用户体验。掌握上述流程后,您可以轻松分发自己的工具软件,无需用户具备编程背景即可使用。

目录

  1. 前言
  2. 环境准备
  3. 基本流程
  4. 开始操作
  5. 1. 环境创建
  6. 1. 创建环境
  7. 2. 进入环境
  8. 3. 安装 pyinstaller
  9. 2. 编码示例
  10. 3. 开始打包
  11. 4. Inno Setup Compiler 操作
  12. 新建脚本
  13. 选择主程序和文件
  14. 设置名称和图标
  15. 导出位置
  16. 运行脚本
  17. 安装效果
  18. 深入:Inno Setup 脚本详解
  19. 常见问题与解决方案
  20. 1. 缺少 DLL 报错
  21. 2. 杀毒软件误报
  22. 3. 打包体积过大
  23. 4. 中文乱码
  24. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Stable Diffusion 图生图功能详解与参数优化指南
  • 基于数据流架构扩展 RAG 提升大模型准确度
  • Arduino BLDC 机器人 IMU 角度读取与 PID 互补滤波控制
  • Stable Diffusion 1.5 皮革服装 LoRA 镜像部署实战
  • Flutter 全方位深入探索与实战指南
  • AIGC 联动 Photoshop 与 Spine 2D 实现 2D 角色骨骼动画拆件
  • 大模型入门教程:基础原理、微调技术与实战指南
  • 程序员职业发展的“内卷化”现象与应对策略
  • 漏洞扫描工具整合使用教程
  • AI 智能体:基于 OpenCode 搭建 Skills 环境与项目实战开发
  • 大模型工作岗位解析与项目经理职责详解
  • 无人机结构设计核心要点解析
  • C++ 模拟实现二叉搜索树
  • 大模型提示工程 (Prompt Engineering) 核心策略与实战
  • 45 岁程序员求职困境:技术精湛为何难获面试机会
  • 混沌工程开源平台解析与测试实践指南
  • Qwen2.5-VL 系列模型正式开源及实测分析
  • 数据结构基础:树的概念与结构详解
  • AI 产品经理转型指南:核心能力与学习路径
  • Python 网络爬虫技术入门与实战指南

相关免费在线工具

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online