build.bat参数解析兼容PowerShell+gitignore修正保留构建脚本
This commit is contained in:
+3
-1
@@ -4,7 +4,9 @@ __pycache__/
|
||||
*.pyo
|
||||
*.egg-info/
|
||||
dist/
|
||||
build/
|
||||
# PyInstaller output (在build目录内),但保留构建脚本
|
||||
build/build/
|
||||
build/*.log
|
||||
|
||||
# Virtual environment
|
||||
venv/
|
||||
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
REM === WindowMsgBot 构建脚本 ===
|
||||
REM 自动化打包和签名流程
|
||||
REM 用法: build.bat /skip-cert /skip-sign
|
||||
REM build.bat --skip-cert --skip-sign (PowerShell兼容)
|
||||
REM build.bat skip-cert skip-sign (无前缀)
|
||||
|
||||
set "SCRIPT_DIR=%~dp0"
|
||||
set "PROJECT_DIR=%SCRIPT_DIR%.."
|
||||
set "PYTHON=%PROJECT_DIR%\.venv311\Scripts\python.exe"
|
||||
set "PYINSTALLER=%PYTHON% -m PyInstaller"
|
||||
|
||||
set "SKIP_CERT=0"
|
||||
set "SKIP_SIGN=0"
|
||||
|
||||
REM 解析参数(兼容 / -- 无前缀 三种写法)
|
||||
:parse_args
|
||||
if "%~1"=="" goto :start_build
|
||||
set "_arg=%~1"
|
||||
set "_arg=!_arg:/=!"
|
||||
set "_arg=!_arg:--=!"
|
||||
if "!_arg!"=="skip-cert" set "SKIP_CERT=1"
|
||||
if "!_arg!"=="skip-sign" set "SKIP_SIGN=1"
|
||||
shift
|
||||
goto :parse_args
|
||||
|
||||
:start_build
|
||||
echo === WindowMsgBot 构建脚本 ===
|
||||
echo 项目目录: %PROJECT_DIR%
|
||||
echo Python: %PYTHON%
|
||||
echo.
|
||||
|
||||
REM 检查Python
|
||||
if not exist "%PYTHON%" (
|
||||
echo 错误: Python不存在: %PYTHON%
|
||||
echo 请先创建虚拟环境
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM 检查PyInstaller
|
||||
"%PYTHON%" -c "import PyInstaller" >nul 2>&1
|
||||
if %errorlevel% neq 0 (
|
||||
echo 安装PyInstaller...
|
||||
"%PYTHON%" -m pip install pyinstaller
|
||||
)
|
||||
|
||||
REM 1. 生成证书(可选)
|
||||
if "%SKIP_CERT%"=="0" (
|
||||
echo 1. 生成自签名证书...
|
||||
if exist "%SCRIPT_DIR%code_signing_cert.pfx" (
|
||||
echo 证书已存在,跳过生成
|
||||
) else (
|
||||
powershell -ExecutionPolicy Bypass -File "%SCRIPT_DIR%generate_cert.ps1"
|
||||
if %errorlevel% neq 0 (
|
||||
echo ⚠ 证书生成失败,继续构建...
|
||||
)
|
||||
)
|
||||
) else (
|
||||
echo 1. 跳过证书生成
|
||||
)
|
||||
|
||||
REM 2. 清理旧构建(只清理PyInstaller输出,保留build目录里的spec和hooks)
|
||||
echo.
|
||||
echo 2. 清理旧构建文件...
|
||||
if exist "%PROJECT_DIR%\build\build" rmdir /s /q "%PROJECT_DIR%\build\build"
|
||||
if exist "%PROJECT_DIR%\dist" rmdir /s /q "%PROJECT_DIR%\dist"
|
||||
|
||||
REM 3. PyInstaller打包
|
||||
echo.
|
||||
echo 3. PyInstaller打包...
|
||||
|
||||
REM 禁用 CUDA 防止 PyInstaller isolated 子进程 access violation 崩溃
|
||||
set "PYTORCH_NO_CUDA_DISPATCH=1"
|
||||
set "CUDA_VISIBLE_DEVICES="
|
||||
|
||||
cd /d "%PROJECT_DIR%"
|
||||
"%PYINSTALLER%" "%SCRIPT_DIR%windowmsgbot.spec" --noconfirm --clean
|
||||
if %errorlevel% neq 0 (
|
||||
echo 错误: PyInstaller打包失败!
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo ✓ 打包完成
|
||||
|
||||
REM 4. 签名(可选)
|
||||
if "%SKIP_SIGN%"=="0" (
|
||||
echo.
|
||||
echo 4. 签名exe文件...
|
||||
if exist "%SCRIPT_DIR%code_signing_cert.pfx" (
|
||||
call "%SCRIPT_DIR%sign.bat"
|
||||
) else (
|
||||
echo ⚠ 证书不存在,跳过签名
|
||||
)
|
||||
) else (
|
||||
echo.
|
||||
echo 4. 跳过签名
|
||||
)
|
||||
|
||||
REM 5. 输出结果
|
||||
echo.
|
||||
echo 5. 构建结果...
|
||||
if exist "%PROJECT_DIR%\dist\WindowMsgBot\WindowMsgBot.exe" (
|
||||
echo ✓ 可执行文件: %PROJECT_DIR%\dist\WindowMsgBot\WindowMsgBot.exe
|
||||
for %%A in ("%PROJECT_DIR%\dist\WindowMsgBot\WindowMsgBot.exe") do echo 大小: %%~zA 字节
|
||||
echo ✓ 输出目录: %PROJECT_DIR%\dist\WindowMsgBot\
|
||||
) else (
|
||||
echo ✗ 可执行文件未生成
|
||||
)
|
||||
|
||||
echo.
|
||||
echo === 构建完成 ===
|
||||
echo 输出目录: %PROJECT_DIR%\dist
|
||||
echo.
|
||||
pause
|
||||
@@ -0,0 +1,105 @@
|
||||
# 生成自签名代码签名证书 - 降低360敏感度
|
||||
# 使用方法: 以管理员身份运行 PowerShell, 执行 .\generate_cert.ps1
|
||||
|
||||
param(
|
||||
[string]$CertPassword = "WindowMsgBot2026",
|
||||
[string]$CertSubject = "CN=WindowMsgBot, O=WindowMsgBot Development",
|
||||
[int]$ValidYears = 5
|
||||
)
|
||||
|
||||
Write-Host "=== 生成自签名代码签名证书 ===" -ForegroundColor Cyan
|
||||
|
||||
# 1. 生成证书
|
||||
Write-Host "1. 生成自签名证书..." -ForegroundColor Yellow
|
||||
$cert = New-SelfSignedCertificate `
|
||||
-Subject $CertSubject `
|
||||
-Type CodeSigningCert `
|
||||
-CertStoreLocation "Cert:\CurrentUser\My" `
|
||||
-NotAfter (Get-Date).AddYears($ValidYears) `
|
||||
-KeyAlgorithm RSA `
|
||||
-KeyLength 2048 `
|
||||
-HashAlgorithm SHA256 `
|
||||
-FriendlyName "WindowMsgBot Code Signing Certificate"
|
||||
|
||||
if (-not $cert) {
|
||||
Write-Error "证书生成失败!"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host " 证书指纹: $($cert.Thumbprint)" -ForegroundColor Green
|
||||
|
||||
# 2. 导出PFX文件
|
||||
Write-Host "2. 导出PFX文件..." -ForegroundColor Yellow
|
||||
$pfxPath = Join-Path $PSScriptRoot "code_signing_cert.pfx"
|
||||
$password = ConvertTo-SecureString -String $CertPassword -Force -AsPlainText
|
||||
|
||||
Export-PfxCertificate `
|
||||
-Cert $cert `
|
||||
-FilePath $pfxPath `
|
||||
-Password $password
|
||||
|
||||
Write-Host " PFX已保存: $pfxPath" -ForegroundColor Green
|
||||
|
||||
# 3. 导出CER文件(公钥)
|
||||
Write-Host "3. 导出CER公钥文件..." -ForegroundColor Yellow
|
||||
$cerPath = Join-Path $PSScriptRoot "code_signing_cert.cer"
|
||||
Export-Certificate `
|
||||
-Cert $cert `
|
||||
-FilePath $cerPath
|
||||
|
||||
Write-Host " CER已保存: $cerPath" -ForegroundColor Green
|
||||
|
||||
# 4. 安装到受信任的根证书颁发机构
|
||||
Write-Host "4. 安装到受信任的根证书颁发机构..." -ForegroundColor Yellow
|
||||
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store(
|
||||
"Root", "LocalMachine")
|
||||
$store.Open("ReadWrite")
|
||||
$store.Add($cert)
|
||||
$store.Close()
|
||||
|
||||
Write-Host " 证书已安装到受信任的根证书存储" -ForegroundColor Green
|
||||
|
||||
# 5. 验证安装
|
||||
Write-Host "5. 验证证书安装..." -ForegroundColor Yellow
|
||||
$installed = Get-ChildItem -Path "Cert:\LocalMachine\Root" |
|
||||
Where-Object { $_.Thumbprint -eq $cert.Thumbprint }
|
||||
|
||||
if ($installed) {
|
||||
Write-Host " ✓ 证书已成功安装到受信任存储" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " ⚠ 证书可能未安装到受信任存储" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# 6. 输出证书信息
|
||||
Write-Host "`n=== 证书信息 ===" -ForegroundColor Cyan
|
||||
Write-Host "主题: $($cert.Subject)"
|
||||
Write-Host "指纹: $($cert.Thumbprint)"
|
||||
Write-Host "有效期: $($cert.NotBefore) 至 $($cert.NotAfter)"
|
||||
Write-Host "用途: $($cert.EnhancedKeyUsageList.FriendlyName -join ', ')"
|
||||
Write-Host "`nPFX密码: $CertPassword" -ForegroundColor Yellow
|
||||
Write-Host "请妥善保管PFX文件和密码!" -ForegroundColor Red
|
||||
|
||||
# 7. 创建证书信息文件
|
||||
Write-Host "7. 创建证书信息文件..." -ForegroundColor Yellow
|
||||
$infoPath = Join-Path $PSScriptRoot "cert_info.txt"
|
||||
@"
|
||||
证书信息
|
||||
========
|
||||
主题: $($cert.Subject)
|
||||
指纹: $($cert.Thumbprint)
|
||||
有效期: $($cert.NotBefore) 至 $($cert.NotAfter)
|
||||
PFX文件: code_signing_cert.pfx
|
||||
CER文件: code_signing_cert.cer
|
||||
PFX密码: $CertPassword
|
||||
|
||||
使用说明
|
||||
========
|
||||
1. PFX文件用于signtool签名
|
||||
2. CER文件可分发给其他人验证签名
|
||||
3. 证书已安装到本机受信任存储
|
||||
"@ | Out-File -FilePath $infoPath -Encoding UTF8
|
||||
|
||||
Write-Host " 证书信息已保存: $infoPath" -ForegroundColor Green
|
||||
|
||||
Write-Host "`n=== 完成 ===" -ForegroundColor Cyan
|
||||
Write-Host "下一步: 使用 sign.bat 脚本签名exe文件" -ForegroundColor Yellow
|
||||
@@ -0,0 +1,20 @@
|
||||
"""PyInstaller hook: 避免 easyocr 默认 hook 触发 collect_submodules('torch') 崩溃。
|
||||
|
||||
PyInstaller 默认 hook-easyocr.py 会调用 collect_submodules('easyocr'),
|
||||
而 easyocr 内部 import torch,导致 isolated 子进程 access violation。
|
||||
本 hook 只列出 easyocr 实际需要的子模块,避开 torch 引用。
|
||||
"""
|
||||
hiddenimports = [
|
||||
'easyocr',
|
||||
'easyocr.easyocr',
|
||||
'easyocr.config',
|
||||
'easyocr.detection',
|
||||
'easyocr.recognition',
|
||||
'easyocr.utils',
|
||||
'easyocr.craft',
|
||||
'easyocr.craft_utils',
|
||||
'easyocr.imgproc',
|
||||
'easyocr.dataset',
|
||||
'easyocr.model',
|
||||
'easyocr.model.vgg_model',
|
||||
]
|
||||
@@ -0,0 +1,41 @@
|
||||
"""PyInstaller hook: 避免 collect_submodules('torch') 在 isolated 子进程中 access violation 崩溃。
|
||||
|
||||
PyInstaller 默认 hook-torch.py 调用 collect_submodules('torch') 遍历全部子模块,
|
||||
在 torch 2.5+ 的 isolated 子进程中会触发 0xC0000005 access violation。
|
||||
本 hook 直接列出实际需要的 torch 子模块,完全避开 collect_submodules。
|
||||
"""
|
||||
# 只列出 bot 实际引用的 torch 子模块(通过 import 分析确认)
|
||||
hiddenimports = [
|
||||
'torch',
|
||||
'torch.nn',
|
||||
'torch.nn.functional',
|
||||
'torch.nn.modules',
|
||||
'torch.nn.modules.activation',
|
||||
'torch.nn.modules.conv',
|
||||
'torch.nn.modules.linear',
|
||||
'torch.nn.modules.module',
|
||||
'torch.nn.modules.normalization',
|
||||
'torch.nn.modules.padding',
|
||||
'torch.nn.modules.pooling',
|
||||
'torch.nn.modules.rnn',
|
||||
'torch.nn.modules.sparse',
|
||||
'torch.nn.modules.dropout',
|
||||
'torch.nn.modules.batchnorm',
|
||||
'torch.nn.modules.loss',
|
||||
'torch.nn.modules.container',
|
||||
'torch.nn.modules.flatten',
|
||||
'torch.nn.modules.pixelshuffle',
|
||||
'torch.nn.modules.upsampling',
|
||||
'torch.nn.modules.channelshuffle',
|
||||
'torch.cuda',
|
||||
'torch.cuda.amp',
|
||||
'torch.tensor',
|
||||
'torch._C',
|
||||
'torch._utils',
|
||||
'torch.storage',
|
||||
'torch.serialization',
|
||||
'torch.types',
|
||||
'torch.classes',
|
||||
'torch.backends',
|
||||
'torch.backends.cudnn',
|
||||
]
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
REM === WindowMsgBot 签名脚本 ===
|
||||
REM 使用自签名证书签名exe文件,降低360敏感度
|
||||
REM 用法: sign.bat [exe路径]
|
||||
|
||||
set "SCRIPT_DIR=%~dp0"
|
||||
set "PROJECT_DIR=%SCRIPT_DIR%.."
|
||||
set "CERT_PFX=%SCRIPT_DIR%code_signing_cert.pfx"
|
||||
set "CERT_PASS=WindowMsgBot2026"
|
||||
set "OUTPUT_DIR=%PROJECT_DIR%\dist"
|
||||
|
||||
REM 如果没有指定exe文件,查找默认的exe(onedir模式在子目录中)
|
||||
if "%~1"=="" (
|
||||
if exist "%OUTPUT_DIR%\WindowMsgBot\WindowMsgBot.exe" (
|
||||
set "EXE_PATH=%OUTPUT_DIR%\WindowMsgBot\WindowMsgBot.exe"
|
||||
) else (
|
||||
set "EXE_PATH=%OUTPUT_DIR%\WindowMsgBot.exe"
|
||||
)
|
||||
) else (
|
||||
set "EXE_PATH=%~1"
|
||||
)
|
||||
|
||||
echo === WindowMsgBot 代码签名 ===
|
||||
echo.
|
||||
|
||||
REM 检查exe文件是否存在
|
||||
if not exist "%EXE_PATH%" (
|
||||
echo 错误: exe文件不存在: %EXE_PATH%
|
||||
echo 请先运行 PyInstaller 构建: pyinstaller build/windowmsgbot.spec
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM 检查证书文件是否存在
|
||||
if not exist "%CERT_PFX%" (
|
||||
echo 错误: 证书文件不存在: %CERT_PFX%
|
||||
echo 请先运行证书生成脚本: powershell -ExecutionPolicy Bypass -File build\generate_cert.ps1
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM 查找signtool.exe
|
||||
set "SIGNTOOL="
|
||||
for %%i in (
|
||||
"%ProgramFiles%\Windows Kits\10\bin\x64\signtool.exe"
|
||||
"%ProgramFiles(x86)%\Windows Kits\10\bin\x64\signtool.exe"
|
||||
"%ProgramFiles%\Windows Kits\10\bin\x86\signtool.exe"
|
||||
"%ProgramFiles(x86)%\Windows Kits\10\bin\x86\signtool.exe"
|
||||
"%ProgramFiles%\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\signtool.exe"
|
||||
) do (
|
||||
if exist %%i (
|
||||
set "SIGNTOOL=%%~i"
|
||||
goto :found_sign
|
||||
)
|
||||
)
|
||||
|
||||
REM 尝试从PATH查找
|
||||
where signtool.exe >nul 2>&1
|
||||
if %errorlevel% equ 0 (
|
||||
set "SIGNTOOL=signtool.exe"
|
||||
goto :found_sign
|
||||
)
|
||||
|
||||
echo 错误: 未找到 signtool.exe
|
||||
echo 请安装 Windows SDK 或 Windows Kits
|
||||
echo 下载地址: https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/
|
||||
pause
|
||||
exit /b 1
|
||||
|
||||
:found_sign
|
||||
echo 使用signtool: %SIGNTOOL%
|
||||
echo.
|
||||
|
||||
REM 1. 签名exe
|
||||
echo 1. 签名exe文件...
|
||||
"%SIGNTOOL%" sign /f "%CERT_PFX%" /p "%CERT_PASS%" /tr http://timestamp.digicert.com /td sha256 /fd sha256 "%EXE_PATH%"
|
||||
if %errorlevel% neq 0 (
|
||||
echo 错误: 签名失败!
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo ✓ 签名成功
|
||||
|
||||
REM 2. 验证签名
|
||||
echo.
|
||||
echo 2. 验证签名...
|
||||
"%SIGNTOOL%" verify /pa "%EXE_PATH%"
|
||||
if %errorlevel% equ 0 (
|
||||
echo ✓ 签名验证通过
|
||||
) else (
|
||||
echo ⚠ 签名验证失败,但签名可能已应用
|
||||
)
|
||||
|
||||
REM 3. 显示签名信息
|
||||
echo.
|
||||
echo 3. 签名信息...
|
||||
"%SIGNTOOL%" verify /v "%EXE_PATH%" 2>nul | findstr /i "Signing"
|
||||
echo.
|
||||
|
||||
REM 4. 复制签名后的exe到项目根目录
|
||||
echo 4. 复制签名后的exe...
|
||||
copy "%EXE_PATH%" "%PROJECT_DIR%\WindowMsgBot_signed.exe" >nul
|
||||
if %errorlevel% equ 0 (
|
||||
echo ✓ 已复制到: %PROJECT_DIR%\WindowMsgBot_signed.exe
|
||||
) else (
|
||||
echo ⚠ 复制失败
|
||||
)
|
||||
|
||||
echo.
|
||||
echo === 完成 ===
|
||||
echo 签名后的exe: %EXE_PATH%
|
||||
echo 备份副本: %PROJECT_DIR%\WindowMsgBot_signed.exe
|
||||
echo.
|
||||
echo 注意: 自签名证书需要在目标机器上安装证书才能验证签名
|
||||
echo 证书文件: %CERT_PFX%
|
||||
echo.
|
||||
pause
|
||||
@@ -0,0 +1,172 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
# WindowMsgBot PyInstaller spec文件
|
||||
# 用法: pyinstaller build/windowmsgbot.spec
|
||||
|
||||
import os
|
||||
import sys
|
||||
from PyInstaller.utils.hooks import collect_submodules, collect_data_files
|
||||
|
||||
# 项目根目录
|
||||
PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(SPEC)))
|
||||
|
||||
# 收集所有需要的子模块
|
||||
hiddenimports = [
|
||||
'uiautomation',
|
||||
'win32gui',
|
||||
'win32con',
|
||||
'win32api',
|
||||
'win32process',
|
||||
'psutil',
|
||||
'PIL',
|
||||
'PIL.Image',
|
||||
'PIL.ImageGrab',
|
||||
'PIL.ImageEnhance',
|
||||
'PIL.ImageFilter',
|
||||
'easyocr',
|
||||
'numpy',
|
||||
'torch',
|
||||
'torchvision',
|
||||
'sklearn',
|
||||
'sklearn.feature_extraction.text',
|
||||
'sklearn.metrics.pairwise',
|
||||
'jieba',
|
||||
'customtkinter',
|
||||
'comtypes',
|
||||
'comtypes.client',
|
||||
'win32com',
|
||||
'win32com.client',
|
||||
'pythoncom',
|
||||
'pywintypes',
|
||||
'ctypes',
|
||||
'ctypes.wintypes',
|
||||
'sqlite3',
|
||||
'json',
|
||||
'hashlib',
|
||||
'difflib',
|
||||
'unicodedata',
|
||||
'signal',
|
||||
'subprocess',
|
||||
'threading',
|
||||
'logging',
|
||||
'traceback',
|
||||
'faulthandler',
|
||||
're',
|
||||
'random',
|
||||
'datetime',
|
||||
'time',
|
||||
'sys',
|
||||
'os',
|
||||
'io',
|
||||
'math',
|
||||
'struct',
|
||||
'codecs',
|
||||
'encodings',
|
||||
'encodings.utf_8',
|
||||
'encodings.gbk',
|
||||
'encodings.gb2312',
|
||||
'encodings.gb18030',
|
||||
]
|
||||
|
||||
# 数据文件
|
||||
datas = [
|
||||
# 知识库目录
|
||||
(os.path.join(PROJECT_ROOT, '知识库'), '知识库'),
|
||||
# 偏旁库
|
||||
(os.path.join(PROJECT_ROOT, 'unicode_radicals.md'), '.'),
|
||||
# 配置文件
|
||||
(os.path.join(PROJECT_ROOT, 'config.json'), '.'),
|
||||
# EasyOCR worker脚本(作为数据文件,运行时提取)
|
||||
(os.path.join(PROJECT_ROOT, 'easyocr_worker.py'), '.'),
|
||||
# 其他必要文件
|
||||
(os.path.join(PROJECT_ROOT, 'auto_reply.py'), '.'),
|
||||
(os.path.join(PROJECT_ROOT, 'knowledge_base.py'), '.'),
|
||||
(os.path.join(PROJECT_ROOT, 'config.py'), '.'),
|
||||
(os.path.join(PROJECT_ROOT, 'gui.py'), '.'),
|
||||
]
|
||||
|
||||
# 收集easyocr数据文件
|
||||
easyocr_datas = collect_data_files('easyocr')
|
||||
datas.extend(easyocr_datas)
|
||||
|
||||
# 分析
|
||||
a = Analysis(
|
||||
[os.path.join(PROJECT_ROOT, 'main.py')],
|
||||
pathex=[PROJECT_ROOT],
|
||||
binaries=[],
|
||||
datas=datas,
|
||||
hiddenimports=hiddenimports,
|
||||
hookspath=[os.path.join(PROJECT_ROOT, 'build', 'hooks')],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[
|
||||
'tkinter.test',
|
||||
'unittest',
|
||||
'test',
|
||||
'distutils',
|
||||
'setuptools',
|
||||
'pip',
|
||||
'pkg_resources',
|
||||
'pydoc',
|
||||
'doctest',
|
||||
'torch.autograd',
|
||||
'torch.testing',
|
||||
'torch.distributed',
|
||||
'torch.fx',
|
||||
'torch.jit',
|
||||
'torch.onnx',
|
||||
'torch.profiler',
|
||||
'torch.sparse',
|
||||
'torch.utils.benchmark',
|
||||
'torch.utils.bottleneck',
|
||||
'torch.utils.checkpoint',
|
||||
'torch.utils.collect_env',
|
||||
'torch.utils.cpp_extension',
|
||||
'torch.utils.data',
|
||||
'torch.utils.deterministic',
|
||||
'torch.utils.dlpack',
|
||||
'torch.utils.file_baton',
|
||||
'torch.utils.hipify',
|
||||
'torch.utils.jit',
|
||||
'torch.utils.mobile_optimizer',
|
||||
'torch.utils.model_zoo',
|
||||
'torch.utils.show_pickle',
|
||||
'torch.utils.tensorboard',
|
||||
'torch.utils.throughput_benchmark',
|
||||
],
|
||||
noarchive=False,
|
||||
)
|
||||
|
||||
# 过滤掉不必要的大文件
|
||||
a.datas = [d for d in a.datas if not d[0].endswith(('.pyc', '.pyo'))]
|
||||
|
||||
# PYZ - Python字节码
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
# EXE - 主程序(onedir模式:只放脚本+PYZ,不嵌入binaries/data)
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
[],
|
||||
exclude_binaries=True, # onedir关键:不嵌入二进制,交给COLLECT
|
||||
name='WindowMsgBot',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=False, # UPX对大型DLL(torch/scipy)常出问题,关掉
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
||||
|
||||
# COLLECT - 收集所有文件到输出目录
|
||||
coll = COLLECT(
|
||||
exe,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
strip=False,
|
||||
upx=False,
|
||||
name='WindowMsgBot',
|
||||
)
|
||||
Binary file not shown.
Reference in New Issue
Block a user