This commit is contained in:
27942
2026-02-26 20:55:59 +08:00
parent 136668147b
commit 3aab3ff071
6 changed files with 52 additions and 3728 deletions

View File

@@ -1,21 +1,41 @@
# -*- mode: python ; coding: utf-8 -*- # -*- mode: python ; coding: utf-8 -*-
# 客户端 GUI 打包配置 # 客户端 GUI 打包配置
# 用法: 在项目根目录执行 pyinstaller build_client.spec # 用法: 在项目根目录 (boss_dp) 执行: pyinstaller build_client.spec
import os import os
_project_root = os.path.dirname(os.path.abspath(SPECPATH)) _spec_dir = os.path.dirname(os.path.abspath(SPECPATH))
_run_client = os.path.join(_spec_dir, 'run_client.py')
if not os.path.isfile(_run_client):
_spec_dir = os.getcwd()
_run_client = os.path.join(_spec_dir, 'run_client.py')
block_cipher = None block_cipher = None
a = Analysis( a = Analysis(
[os.path.join(_project_root, 'run_client.py')], [_run_client],
pathex=[_project_root], pathex=[_spec_dir],
binaries=[], binaries=[],
datas=[], datas=[],
hiddenimports=[ hiddenimports=[
'client_gui', 'client_gui',
'client_gui.main', 'client_gui.main',
'client_gui.config_store', 'client_gui.config_store',
'worker',
'worker.main',
'worker.ws_client',
'worker.bit_browser',
'worker.browser_control',
'worker.config',
'worker.tasks',
'worker.tasks.registry',
'worker.tasks.base',
'worker.tasks.boss_recruit',
'worker.tasks.check_login',
'tunnel',
'tunnel.client',
'tunnel.protocol',
'common',
'common.protocol',
'PyQt5', 'PyQt5',
'PyQt5.QtCore', 'PyQt5.QtCore',
'PyQt5.QtWidgets', 'PyQt5.QtWidgets',

View File

@@ -72,21 +72,23 @@ def _is_frozen() -> bool:
return getattr(sys, "frozen", False) return getattr(sys, "frozen", False)
def _get_worker_launcher() -> tuple[str, str]: def _get_worker_launcher() -> tuple[str, str, bool]:
"""返回 (可执行路径, 工作目录, 是否用 --worker 模式)。"""
if _is_frozen(): if _is_frozen():
exe_dir = os.path.dirname(sys.executable) exe_dir = os.path.dirname(sys.executable)
worker_exe = os.path.join(exe_dir, "worker.exe") return sys.executable, exe_dir, True
if os.path.isfile(worker_exe):
return worker_exe, exe_dir
project_root = get_project_root() project_root = get_project_root()
return sys.executable, project_root return sys.executable, project_root, False
def run_worker(server_url: str, worker_id: str, worker_name: str, log_callback) -> subprocess.Popen | None: def run_worker(server_url: str, worker_id: str, worker_name: str, log_callback) -> subprocess.Popen | None:
"""启动 Worker 子进程。""" """启动 Worker 子进程(同一 exe 的 --worker 模式或 python -m worker.main"""
launcher, cwd = _get_worker_launcher() launcher, cwd, use_worker_flag = _get_worker_launcher()
is_python = launcher == sys.executable if use_worker_flag:
if is_python: cmd = [launcher, "--worker", "--server", server_url, "--worker-id", worker_id, "--worker-name", worker_name]
env = os.environ
encoding = "gbk" if sys.platform == "win32" else "utf-8"
else:
cmd = [ cmd = [
launcher, "-m", "worker.main", launcher, "-m", "worker.main",
"--server", server_url, "--server", server_url,
@@ -95,11 +97,6 @@ def run_worker(server_url: str, worker_id: str, worker_name: str, log_callback)
] ]
env = {**os.environ, "PYTHONIOENCODING": "utf-8"} env = {**os.environ, "PYTHONIOENCODING": "utf-8"}
encoding = "utf-8" encoding = "utf-8"
else:
cmd = [launcher, "--server", server_url, "--worker-id", worker_id, "--worker-name", worker_name]
env = os.environ
# worker.exe 在 Windows 上可能用 GBK 输出
encoding = "gbk" if sys.platform == "win32" else "utf-8"
try: try:
return subprocess.Popen( return subprocess.Popen(
cmd, cwd=cwd, env=env, cmd, cwd=cwd, env=env,

View File

@@ -1,11 +1,22 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
客户端 GUI 启动入口 客户端统一入口:根据参数决定启动 GUI 或 Worker 模式
使用方式: python run_client.py - 无参数 / 正常启动 → GUI 界面
- 带 --worker 参数 → Worker 模式(由 GUI 点击「启动」时调用)
""" """
from __future__ import annotations from __future__ import annotations
from client_gui.main import main import sys
def main():
if "--worker" in sys.argv:
from worker.main import main as worker_main
worker_main()
else:
from client_gui.main import main as gui_main
gui_main()
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@@ -25,6 +25,7 @@ logger = logging.getLogger("worker.main")
def parse_args(): def parse_args():
parser = argparse.ArgumentParser(description="Browser Control Worker Agent") parser = argparse.ArgumentParser(description="Browser Control Worker Agent")
parser.add_argument("--worker", action="store_true", help=argparse.SUPPRESS)
parser.add_argument( parser.add_argument(
"--server", "--server",
default=config.SERVER_WS_URL, default=config.SERVER_WS_URL,

View File

@@ -25,18 +25,8 @@ python app.py
### 方式 B打包为 exe推荐无需 Python ### 方式 B打包为 exe推荐无需 Python
1. 安装 PyInstaller`pip install pyinstaller` 1. 安装 PyInstaller`pip install pyinstaller`
2. 在项目根目录执行打包: 2. 在项目根目录执行打包:`pyinstaller build_client.spec`
```bash 3.`dist/BOSS直聘Worker客户端/` 文件夹发给客户,客户双击 `BOSS直聘Worker客户端.exe` 即可使用GUI 与 Worker 已合并为同一程序,无需 worker.exe
# 打包客户端 GUI
pyinstaller build_client.spec
# 打包 Worker供 GUI 的「启动」按钮调用)
pyinstaller build_worker.spec
```
3. 将生成的文件合并:
- `dist/BOSS直聘Worker客户端/` 为 GUI 输出目录
- 将 `dist/worker/worker.exe` 复制到 `dist/BOSS直聘Worker客户端/` 目录内
4. 将整个 `BOSS直聘Worker客户端` 文件夹发给客户,客户双击 `BOSS直聘Worker客户端.exe` 即可使用
### GUI 功能说明 ### GUI 功能说明

File diff suppressed because it is too large Load Diff