python打包exe程序,如何加入注册码功能?
87 2025-07-19 10:51
要将 Python 程序打包为带注册码功能的
.exe
,推荐使用 PyInstaller 工具,并结合注册码机制实现授权验证。以下是完整实现步骤:✅ 一、打包为 EXE(使用 PyInstaller)
-
安装 PyInstaller:
bash
复制
pip install pyinstaller
-
打包命令(单文件、无控制台):
bash
复制
pyinstaller -F -w your_script.py
-
-F
:单文件打包 -
-w
:去掉控制台窗口(GUI程序适用)
✅ 二、注册码机制实现思路
推荐方式:机器码 + 注册码 模式
-
程序首次运行时生成机器码(如硬盘序列号)
-
用户将机器码发给管理员
-
管理员用注册机加密后生成注册码
-
用户输入注册码验证,验证通过则写入本地授权文件
✅ 三、注册码功能代码示例(基于硬盘序列号)
1. 获取机器码(C盘卷序列号)
Python
复制
import win32api
def get_machine_code():
return str(win32api.GetVolumeInformation("C:\\")[1])
2. 注册码生成与验证(使用 DES + Base64)
Python
复制
import base64
from pyDes import des, CBC, PAD_PKCS5
DES_KEY = "A1B2C3D4"
DES_IV = "\x11\x22\x33\x44\x55\x66\x77\x88"
def encrypt(text):
k = des(DES_KEY, CBC, DES_IV, padmode=PAD_PKCS5)
return base64.b64encode(k.encrypt(text)).decode()
def decrypt(ciphertext):
k = des(DES_KEY, CBC, DES_IV, padmode=PAD_PKCS5)
return k.decrypt(base64.b64decode(ciphertext)).decode()
3. 注册流程
Python
复制
import os
def register():
if os.path.exists("license.key"):
with open("license.key") as f:
encrypted_code = f.read()
if decrypt(encrypted_code) == get_machine_code():
return True
reg_code = input("请输入注册码:")
try:
if decrypt(reg_code) == get_machine_code():
with open("license.key", "w") as f:
f.write(reg_code)
print("注册成功!")
return True
else:
print("注册码无效!")
except Exception:
print("注册码格式错误!")
return False
✅ 四、管理员注册机(单独脚本)
Python
复制
# 管理员使用:输入用户机器码,生成注册码
machine_code = input("输入用户机器码:")
print("注册码为:", encrypt(machine_code))
✅ 五、打包注意事项
-
加密打包(防止反编译):
bash
复制
pyinstaller -F -w --key=yourpassword your_script.py
-
使用 UPX 压缩体积:
bash
复制
pyinstaller -F -w --upx-dir=upx路径 your_script.py
✅ 六、完整流程总结
表格
复制
步骤 | 操作方 | 内容 |
---|---|---|
1 | 用户 | 运行程序,获取机器码 |
2 | 用户 | 将机器码发给管理员 |
3 | 管理员 | 用注册机生成注册码 |
4 | 用户 | 输入注册码激活 |
5 | 程序 | 验证注册码并保存授权文件 |
如需图形界面注册窗口,可结合
tkinter
或 PyQt
实现,注册逻辑不变。
结合 tkinter实现图形界面注册窗口
下面给出一个可直接运行的完整示例,把注册码机制(机器码 → 加密注册码 → 验证)与 Tkinter 图形界面整合在一起。
目录结构只需两个文件即可运行:
目录结构只需两个文件即可运行:
复制
project/
├─ main.py # 主程序(带 Tkinter 注册窗口)
└─ regmaker.py # 管理员注册机(单独脚本,给管理员用)
🔧 1. 安装依赖
bash
复制
pip install pyinstaller pyDes
📁 2. main.py(主程序 + Tkinter 注册界面)
Python
复制
# main.py
import os
import tkinter as tk
from tkinter import messagebox
import win32api
import base64
from pyDes import des, CBC, PAD_PKCS5
# DES 密钥和 IV(必须与 regmaker.py 保持一致)
DES_KEY = b"A1B2C3D4"
DES_IV = b"\x11\x22\x33\x44\x55\x66\x77\x88"
# ------------------- 加解密 -------------------
def encrypt(text: str) -> str:
k = des(DES_KEY, CBC, DES_IV, padmode=PAD_PKCS5)
return base64.b64encode(k.encrypt(text.encode())).decode()
def decrypt(ciphertext: str) -> str:
k = des(DES_KEY, CBC, DES_IV, padmode=PAD_PKCS5)
return k.decrypt(base64.b64decode(ciphertext.encode())).decode()
# ------------------- 机器码 -------------------
def get_machine_code() -> str:
return str(win32api.GetVolumeInformation("C:\\")[1])
# ------------------- 注册逻辑 -------------------
LICENSE_FILE = "license.key"
def is_licensed() -> bool:
"""检查是否已经注册"""
if not os.path.exists(LICENSE_FILE):
return False
try:
with open(LICENSE_FILE, "r", encoding="utf-8") as f:
reg_code = f.read().strip()
return decrypt(reg_code) == get_machine_code()
except Exception:
return False
def save_license(reg_code: str) -> bool:
"""保存注册码,返回是否成功"""
try:
if decrypt(reg_code) == get_machine_code():
with open(LICENSE_FILE, "w", encoding="utf-8") as f:
f.write(reg_code)
return True
except Exception:
pass
return False
# ------------------- Tkinter GUI -------------------
class RegWindow(tk.Toplevel):
def __init__(self, parent):
super().__init__(parent)
self.title("软件注册")
self.geometry("300x220")
self.resizable(False, False)
self.grab_set() # 模态窗口
tk.Label(self, text="机器码:").pack(pady=5)
self.machine_label = tk.Label(self, text=get_machine_code(), bg="#f0f0f0", width=35)
self.machine_label.pack()
tk.Label(self, text="请输入注册码:").pack(pady=5)
self.reg_entry = tk.Entry(self, width=35)
self.reg_entry.pack()
tk.Button(self, text="注册", width=15, command=self.on_register).pack(pady=10)
def on_register(self):
reg_code = self.reg_entry.get().strip()
if not reg_code:
messagebox.showerror("错误", "注册码不能为空!")
return
if save_license(reg_code):
messagebox.showinfo("成功", "注册成功!请重启程序。")
self.destroy()
else:
messagebox.showerror("失败", "注册码无效!")
# ------------------- 主程序入口 -------------------
def main():
root = tk.Tk()
root.withdraw() # 先隐藏主窗口
if not is_licensed():
RegWindow(root)
root.wait_window() # 等待注册窗口关闭
if not is_licensed():
messagebox.showerror("未注册", "软件未注册,即将退出。")
return
# 这里开始写真正的主程序逻辑
root.deiconify()
root.title("正式版主程序")
tk.Label(root, text="欢迎使用正式版!", font=("微软雅黑", 16)).pack(pady=50)
root.geometry("300x200")
root.mainloop()
if __name__ == "__main__":
main()
📁 3. regmaker.py(管理员注册机)
Python
复制
# regmaker.py
import base64
from pyDes import des, CBC, PAD_PKCS5
DES_KEY = b"A1B2C3D4"
DES_IV = b"\x11\x22\x33\x44\x55\x66\x77\x88"
def encrypt(text: str) -> str:
k = des(DES_KEY, CBC, DES_IV, padmode=PAD_PKCS5)
return base64.b64encode(k.encrypt(text.encode())).decode()
if __name__ == "__main__":
machine_code = input("请输入用户机器码:").strip()
print("注册码:", encrypt(machine_code))
🚀 4. 打包成 EXE(单文件、无控制台)
bash
复制
pyinstaller -F -w main.py
打包后得到
main.exe
;把 regmaker.py
单独给管理员即可。✅ 使用流程
-
用户第一次运行
main.exe
,弹出注册窗口,显示机器码。 -
用户把机器码发给管理员。
-
管理员运行
python regmaker.py
,输入机器码,得到注册码。 -
用户复制注册码到窗口,点击“注册”,验证通过后生成
license.key
,下次启动直接跳过注册窗口。
全部评论