前言
虽然很多开发者专注于 Web 开发,但对 Python 的众多开源项目一直都很关注。像 Stable Diffusion 的 AI 绘画,以及 So-VITS-SVC 音色替换等项目的源码部署文档通常比较完善。尽管如此,对于刚入门或本地环境搭建容易踩坑的同学来说,直接运行源码往往不太友好。针对这一现象,网上已有各种解决方案提供一键部署,无需安装 Python 环境,无需下载各种依赖包,点击 exe 即可使用。
那么这些方案是如何实现的呢?很多人会想到 PyInstaller。它确实可以解决整体环境的打包问题,但有时候一些图标和依赖文件需要放在一起才能正常使用,类似于绿色桌面工具。有没有方法对这个进一步封装,就是点击 exe 后需要安装,然后安装后才是项目的文件,还可以卸载?答案是使用 Inno Setup Compiler。接下来我将用一个 GUI 的小 demo 完成 exe 打包和进一步安装打包。

环境准备
为了确保打包过程顺利,建议准备以下环境:
- Python 3.8 及以上版本
- Tkinter (Python 自带 GUI 库)
- PyInstaller 6.3.0 或更高版本
- Inno Setup Compiler (用于制作安装包)
建议使用 Conda 创建独立的虚拟环境,避免系统全局环境冲突。
基本流程
- 环境创建:用 conda 单独创建一个虚拟环境,例如
tools_env。 - 编写代码:编写一个 tkinter 应用,为了美观,准备尺寸 32x32 和 64x64 的图标文件。
- PyInstaller 打包:将应用打成文件包(含 exe),生成 dist 目录。
- 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
(tk.Tk):
():
().__init__()
.title()
:
.iconbitmap()
:
.geometry()
.resizable(, )
.style = ttk.Style()
.main_color = .cget()
.style.configure(,
padding=,
relief=,
background=,
foreground=,
font=(, , ))
.style.configure(,
font=(, , ))
.style.configure(,
padding=,
font=(, ))
.create_widgets()
():
.path_label = ttk.Label(, text=)
.path_label.grid(row=, sticky=tk.W, pady=, padx=)
.path = tk.StringVar()
.path_entry = ttk.Entry(, width=, textvariable=.path)
.path_entry.grid(row=, column=, sticky=tk.E, pady=)
.rename_label = ttk.Label(, text=)
.rename_label.grid(row=, sticky=tk.W, pady=, padx=)
.rename = tk.StringVar()
.rename_entry = ttk.Entry(, width=, textvariable=.rename)
.rename_entry.grid(row=, column=, sticky=tk.E, pady=)
.msg_text = tk.Text(, height=, width=, wrap=)
.msg_text.grid(row=, column=, sticky=tk.W, pady=)
.msg_text.configure(bd=, relief=, bg=.main_color)
ttk.Button(, text=, command=.start_program).grid(row=, column=, sticky=tk.W, pady=, padx=)
ttk.Button(, text=, command=.about).grid(row=, column=, sticky=tk.W, padx=)
():
path = .path.get()
rename = .rename.get()
path == rename == :
messagebox.showwarning(, )
os.path.isdir(path):
messagebox.showwarning(, )
i =
FileList = os.listdir(path)
files FileList:
oldDirPath = os.path.join(path, files)
.msg_text.delete(, tk.END)
.msg_text.insert(tk.END, )
os.path.isdir(oldDirPath):
fileName = os.path.splitext(files)[]
fileType = os.path.splitext(files)[].lower()
newDirPath = os.path.join(path, )
:
os.rename(oldDirPath, newDirPath)
i +=
Exception e:
()
messagebox.showinfo(, )
():
messagebox.showinfo(, )
():
.destroy()
__name__ == :
app = Application()
app.mainloop()









