add ntfsfix

This commit is contained in:
zj
2026-02-09 21:58:27 +08:00
parent 0112e4d3b1
commit 4a59323398
5 changed files with 210 additions and 161 deletions

231
build.sh
View File

@@ -1,164 +1,113 @@
#!/bin/bash
#
# Linux 存储管理器 - PyInstaller 打包脚本
# 自动安装依赖并打包应用程序
# Linux 存储管理器 - PyInstaller 打包脚本 (简化版)
# 直接打包,仅保留 dist 目录中的最终文件
#
set -e
echo ""
echo "╔══════════════════════════════════════════════════════════════╗"
echo "║ Linux 存储管理器 - PyInstaller 打包工具 ║"
echo "╚══════════════════════════════════════════════════════════════╝"
echo ""
# 检查 Python3
if ! command -v python3 &> /dev/null; then
echo "✗ 错误: 未找到 python3"
echo " 请先安装 Python 3.6+"
exit 1
fi
PYTHON_VERSION=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
echo " Python 版本: $PYTHON_VERSION"
# 检查主程序文件
if [ ! -f "mainwindow_tkinter.py" ] && [ ! -f "mainwindow.py" ]; then
echo "✗ 错误: 未找到主程序文件"
echo " 请确保在包含 mainwindow_tkinter.py 或 mainwindow.py 的目录中运行此脚本"
exit 1
fi
echo ""
echo "═══════════════════════════════════════════════════════════════"
echo " 步骤 1/4: 安装依赖包"
echo "═══════════════════════════════════════════════════════════════"
# 检测是否为外部管理环境 (PEP 668)
IS_EXTERNALLY_MANAGED=0
if python3 -c "import sys; sys.exit(0 if (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix) or 'VIRTUAL_ENV' in __import__('os').environ else 1)" 2>/dev/null; then
echo " 检测到在虚拟环境中"
IS_EXTERNALLY_MANAGED=0
elif python3 -c "import sysconfig; import os; print(os.path.exists(os.path.join(sysconfig.get_path('stdlib'), 'EXTERNALLY-MANAGED')))" | grep -q "True"; then
echo " 检测到外部管理环境 (PEP 668)"
IS_EXTERNALLY_MANAGED=1
fi
# 安装依赖
install_deps() {
local EXTRA_ARGS=""
if [ "$IS_EXTERNALLY_MANAGED" -eq 1 ]; then
EXTRA_ARGS="--break-system-packages"
echo " 使用 --break-system-packages 选项"
fi
# 安装/升级 pip
python3 -m pip install --upgrade pip $EXTRA_ARGS 2>/dev/null || {
echo " pip 升级失败,继续安装..."
}
# 安装 pyinstaller 和 pexpect
pip3 install pyinstaller pexpect $EXTRA_ARGS || {
return 1
}
return 0
}
if ! install_deps; then
echo " 尝试使用 sudo 安装依赖..."
sudo pip3 install pyinstaller pexpect --break-system-packages 2>/dev/null || {
echo ""
echo "✗ 依赖安装失败"
echo ""
echo " 您可以选择以下方式安装:"
echo ""
echo " 方式 1 - 创建虚拟环境 (推荐):"
echo " python3 -m venv venv"
echo " source venv/bin/activate"
echo " pip install pyinstaller pexpect"
echo " ./build.sh"
echo ""
echo " 方式 2 - 使用系统包管理器 (Arch):"
echo " sudo pacman -S python-pyinstaller python-pexpect"
echo " ./build.sh"
echo ""
echo " 方式 3 - 强制安装 (有风险):"
echo " pip3 install pyinstaller pexpect --break-system-packages"
echo " ./build.sh"
echo ""
exit 1
}
fi
echo ""
echo "═══════════════════════════════════════════════════════════════"
echo " 步骤 2/4: 清理构建文件"
echo "═══════════════════════════════════════════════════════════════"
# 清理旧文件
rm -rf build dist __pycache__
rm -f mainwindow*.spec
echo " 已清理构建文件"
echo ""
echo "═══════════════════════════════════════════════════════════════"
echo " 步骤 3/4: PyInstaller 打包"
echo "═══════════════════════════════════════════════════════════════"
# 确定主文件
MAIN_SCRIPT="mainwindow_tkinter.py"
if [ ! -f "$MAIN_SCRIPT" ]; then
MAIN_SCRIPT="mainwindow.py"
fi
echo " 打包文件: $MAIN_SCRIPT"
# 检查 tkinter
if ! python3 -c "import tkinter" 2>/dev/null; then
echo "错误: 未找到 tkinter 模块"
exit 1
fi
# 获取 tkinter 路径
TKINTER_INFO=$(python3 << 'EOF'
import tkinter
import os
import sys
tcl = tkinter.Tcl()
tk_version = tcl.call("info", "tclversion")
tk_lib = tcl.call("info", "library")
print(f"TK_VERSION:{tk_version}")
print(f"TK_LIBRARY:{tk_lib}")
tkinter_file = tkinter.__file__
print(f"TKINTER_FILE:{tkinter_file}")
tcl_lib = os.path.dirname(tk_lib)
print(f"TCL_LIBRARY:{tcl_lib}")
import sysconfig
lib_dynload = os.path.join(sysconfig.get_config_var('LIBDIR'), f"python{sys.version_info.major}.{sys.version_info.minor}", "lib-dynload")
if not os.path.exists(lib_dynload):
lib_dynload = os.path.join(sysconfig.get_config_var('LIBDIR'), "lib-dynload")
print(f"LIB_DYNLOAD:{lib_dynload}")
EOF
)
TK_VERSION=$(echo "$TKINTER_INFO" | grep "TK_VERSION:" | cut -d: -f2)
TK_LIBRARY=$(echo "$TKINTER_INFO" | grep "TK_LIBRARY:" | cut -d: -f2)
TCL_LIBRARY=$(echo "$TKINTER_INFO" | grep "TCL_LIBRARY:" | cut -d: -f2)
LIB_DYNLOAD=$(echo "$TKINTER_INFO" | grep "LIB_DYNLOAD:" | cut -d: -f2)
PYTHON_VERSION=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
# 查找 _tkinter 共享库
TKINTER_SO=""
for pattern in "_tkinter.cpython-${PYTHON_VERSION//./}m-x86_64-linux-gnu.so" "_tkinter.cpython-${PYTHON_VERSION//./}-x86_64-linux-gnu.so" "_tkinter.so"; do
if [ -f "$LIB_DYNLOAD/$pattern" ]; then
TKINTER_SO="$LIB_DYNLOAD/$pattern"
break
fi
done
if [ -z "$TKINTER_SO" ]; then
TKINTER_SO=$(find $LIB_DYNLOAD -name "_tkinter*.so" 2>/dev/null | head -1)
fi
# 构建 PyInstaller 参数
PYINSTALLER_ARGS=(
--onefile
--name "linux-storage-manager"
--clean
--noconfirm
--console
--hidden-import "tkinter"
--hidden-import "tkinter.ttk"
--hidden-import "tkinter.scrolledtext"
--hidden-import "tkinter.messagebox"
--hidden-import "tkinter.filedialog"
--hidden-import "tkinter.simpledialog"
--hidden-import "_tkinter"
)
# 添加 tkinter 库文件
if [ -n "$TKINTER_SO" ]; then
PYINSTALLER_ARGS+=(--add-binary "$TKINTER_SO:.")
fi
if [ -d "$TCL_LIBRARY" ]; then
PYINSTALLER_ARGS+=(--add-data "$TCL_LIBRARY:tcl")
fi
if [ -d "$TK_LIBRARY" ]; then
PYINSTALLER_ARGS+=(--add-data "$TK_LIBRARY:tk")
fi
# 查找并添加其他 Tcl/Tk 文件
for dir in /usr/lib64/tcl$TK_VERSION /usr/lib/tcl$TK_VERSION /usr/share/tcltk /usr/lib/tcltk /usr/lib64/tcltk; do
if [ -d "$dir" ]; then
PYINSTALLER_ARGS+=(--add-data "$dir:tcltk")
fi
done
# 执行打包
python3 -m PyInstaller \
--onefile \
--name "linux-storage-manager" \
--clean \
--noconfirm \
--console \
"$MAIN_SCRIPT"
python3 -m PyInstaller "${PYINSTALLER_ARGS[@]}" "$MAIN_SCRIPT"
echo ""
echo "═══════════════════════════════════════════════════════════════"
echo " 步骤 4/4: 创建桌面快捷方式"
echo "═══════════════════════════════════════════════════════════════"
cat > linux-storage-manager.desktop << 'EOF'
[Desktop Entry]
Name=Linux 存储管理器
Comment=Linux 存储管理工具
Exec=/usr/local/bin/linux-storage-manager
Icon=drive-harddisk
Terminal=false
Type=Application
Categories=System;Utility;
Keywords=storage;disk;partition;raid;lvm;
EOF
echo " 已创建桌面文件: linux-storage-manager.desktop"
echo " 安装命令: sudo cp linux-storage-manager.desktop /usr/share/applications/"
# 检查输出
# 检查结果
if [ -f "dist/linux-storage-manager" ]; then
SIZE=$(du -h dist/linux-storage-manager | cut -f1)
echo ""
echo "╔══════════════════════════════════════════════════════════════╗"
echo "║ 打包成功! ║"
echo "╚══════════════════════════════════════════════════════════════╝"
echo ""
echo "打包成功!"
echo " 输出文件: dist/linux-storage-manager"
echo " 文件大小: $SIZE"
echo ""
echo " 使用方法:"
echo " 直接运行: sudo dist/linux-storage-manager"
echo " 安装到系统: sudo cp dist/linux-storage-manager /usr/local/bin/"
echo ""
echo " 运行命令: sudo dist/linux-storage-manager"
else
echo "打包失败: 未找到输出文件"
echo "打包失败"
exit 1
fi