用户报告:"自动配置似乎无效"
现象:
- 通过服务端 GUI 生成的客户端安装包
- 运行后提示需要配置 CLIENT_ID 和 CLIENT_TOKEN
- 虽然打包时已生成预配置的
.env文件,但客户端读取不到
原代码(package_builder.py):
datas=[
(r'{self.client_dir / "agent"}', 'agent'),
(r'{self.client_dir / ".env"}', '.'), # ← 错误:引用原始目录
],问题:
.env文件在打包前被生成到temp_client_dir / "client" / ".env"- 但 PyInstaller 引用的是
self.client_dir / ".env"(原始目录) - 如果原始目录没有
.env或内容不对,就会打包错误的配置
原代码(config.py):
class Config:
env_file = ".env" # ← 相对路径,打包后找不到问题:
- 打包后的文件结构:
client.exe └── _internal/ ├── agent/ ├── .env # 配置文件在这里 └── ... - 但相对路径
.env会在当前工作目录查找 - 工作目录可能不是程序所在目录
- 导致找不到配置文件
修改(package_builder.py):
def _generate_spec_file(self, main_script: str, client_name: str, temp_client_dir: Path) -> str:
# 使用临时目录中的文件(包含预配置的 .env)
agent_path = temp_client_dir / "client" / "agent"
env_path = temp_client_dir / "client" / ".env" # ← 正确:引用生成的配置
return f"""
datas=[
(r'{agent_path}', 'agent'),
(r'{env_path}', '.'), # ← 打包生成的配置
],
"""效果:
- 打包时使用临时目录中生成的
.env文件 - 该文件包含预配置的 CLIENT_ID 和 CLIENT_TOKEN
- 确保打包的配置是正确的
修改(config.py):
def get_env_file_path():
"""获取 .env 文件路径,支持打包和开发环境"""
# 如果是 PyInstaller 打包后的环境
if getattr(sys, 'frozen', False):
# 打包后,.env 在 _internal 目录
base_path = Path(sys._MEIPASS) # PyInstaller 临时目录
env_path = base_path / ".env"
if env_path.exists():
return str(env_path)
# 备选:程序所在目录
exe_dir = Path(sys.executable).parent
env_path = exe_dir / ".env"
if env_path.exists():
return str(env_path)
# 开发环境:查找多个可能的位置
possible_paths = [
Path(".env"), # 当前目录
Path(__file__).parent.parent / ".env", # client/.env
Path(__file__).parent.parent.parent / "client" / ".env", # 项目根/client/.env
]
for path in possible_paths:
if path.exists():
return str(path)
return ".env"
class ClientSettings(BaseSettings):
class Config:
env_file = get_env_file_path() # ← 动态获取路径效果:
- 打包后自动使用
sys._MEIPASS目录(PyInstaller 特殊变量) - 开发环境自动查找多个可能的位置
- 兼容各种运行环境
客户端名称_client.exe
└── _internal/
├── agent/
│ ├── __init__.py
│ ├── config.py # 包含查找逻辑
│ ├── ws_client.py
│ └── ...
├── .env # 预配置的文件(包含 CLIENT_ID 和 TOKEN)
├── PyQt5/
└── ...(其他依赖)
运行时:
config.py检测到sys.frozen = True(打包环境)- 使用
sys._MEIPASS获取_internal目录路径 - 拼接得到
.env文件路径:_internal/.env - 成功加载预配置的 CLIENT_ID 和 TOKEN
必须重新生成才能应用修复:
1. 启动服务端 GUI
start_server_gui.bat
2. 登录管理平台
admin / admin123
3. 客户端管理
→ 选择客户端
→ 点击"生成安装包"
4. 等待完成(2-5分钟)
5. 测试新安装包
→ 解压 .zip
→ 运行 .exe
→ 应该自动连接,无需配置
运行客户端后,应该:
- ✅ 不提示 "未配置 CLIENT_ID"
- ✅ 不提示 "未配置 CLIENT_TOKEN"
- ✅ 自动连接到服务器
- ✅ 连接状态显示 "🟢 已连接"
如果还有问题,可以添加调试代码:
临时修改(client_gui.py):
def load_config(self):
"""加载配置"""
# 添加调试信息
print(f"配置文件路径: {settings.Config.env_file}")
print(f"CLIENT_ID: {settings.CLIENT_ID}")
print(f"CLIENT_TOKEN: {settings.CLIENT_TOKEN[:10]}..." if settings.CLIENT_TOKEN else "未配置")
self.server_url_input.setText(settings.SERVER_URL)
# ...重新打包并运行,查看输出。
方式1: 使用 PyInstaller 分析工具
pyi-archive_viewer client.exe
# 输入: toc
# 查找: .env方式2: 手动检查
运行程序时,在任务管理器中找到进程
查看其临时目录(通常在 %TEMP%)
应该能找到解压出来的 _internal/.env
修复前:
1. 解压安装包
2. 运行 client.exe
3. 提示需要配置 ❌
4. 需要手动填写 CLIENT_ID 和 TOKEN ❌
5. 点击保存配置 ❌
6. 重新启动客户端 ❌
修复后:
1. 解压安装包
2. 运行 client.exe
3. 自动连接服务器 ✅
4. 无需任何配置 ✅
5. 开箱即用 ✅
修复前:
[ERROR] 未配置 CLIENT_ID
[ERROR] 配置验证失败
修复后:
[INFO] 加载配置文件: C:\Users\...\AppData\Local\Temp\_MEI123456\.env
[INFO] CLIENT_ID: uuid-xxx-xxx-xxx
[INFO] 连接服务器: http://192.168.1.100:8000
[INFO] WebSocket 连接成功
- PyInstaller 打包后运行时创建临时目录
- 所有打包的文件解压到该临时目录
sys._MEIPASS指向该目录- 程序退出后自动清理
示例路径:
C:\Users\username\AppData\Local\Temp\_MEI123456\
加载顺序:
- 环境变量(优先级最高)
.env文件(通过env_file指定)- 默认值(类定义中的值)
我们的修改:
- 动态计算
env_file路径 - 确保在各种环境中都能找到正确的文件
旧安装包不会自动修复:
- 需要用新代码重新生成
- 已分发的旧包需要更新
不影响开发:
- 修改后的代码仍然兼容开发环境
- 可以继续使用
python client_gui.py运行 .env文件查找逻辑自动适配
环境变量优先:
# 即使 .env 文件存在,环境变量仍然优先
set CLIENT_ID=test-id
set CLIENT_TOKEN=test-token
client.exe # 使用环境变量的值这个特性可以用于:
- 临时覆盖配置
- CI/CD 环境
- Docker 容器
排查步骤:
- 确认使用的是新生成的安装包
- 检查生成时间戳
- 删除旧的安装包避免混淆
- 查看客户端日志文件
排查步骤:
- 检查生成安装包时使用的 CLIENT_ID 和 TOKEN 是否正确
- 在服务端 GUI 中查看客户端信息
- 确认服务器地址正确
不是配置问题:
- 配置加载正常
- 但无法连接服务器
- 检查网络、防火墙、服务器状态
server-gui/gui/package_builder.py- 打包逻辑修复client/agent/config.py- 配置加载逻辑修复
- PACKAGING_FIX.md - 依赖缺失问题
- CLIENT_PACKAGE_GUIDE.md - 打包完整指南
- BACKGROUND_MODE_GUIDE.md - 后台运行指南
修复版本: v1.2.1
修复日期: 2025-12-12
影响范围: 所有通过安装包生成功能创建的客户端
解决状态: ✅ 已修复,需重新生成安装包