Skip to content

Releases: rozx/DeepUnzip

v2.0.0

Choose a tag to compare

@github-actions github-actions released this 25 Oct 17:31
2aca018

DeepUnzip v2.0.0

发布日期 / Release date:2026-10-25

2.0.0 是一次大版本更新:项目改名为深度解压(DeepUnzip),解压流程重写为按轮处理的“工作池”,散落在不同压缩包里的分卷也能自动凑齐;终端输出全面改版,支持五种语言,并新增 --json 输出和退出码。

Version 2.0.0 is a major release. The project is renamed DeepUnzip, extraction is rebuilt as a work pool that runs in rounds and assembles volumes spread across different archives, the terminal output is redesigned and speaks five languages, and --json output and exit codes are added.

改名 / Renamed

Complex Unzip Tool v2(复杂解压工具 v2)改名为深度解压(DeepUnzip)。新旧名称对照如下,GitHub 上的旧链接会自动跳转到新仓库。

Complex Unzip Tool v2 is now DeepUnzip. The old and new names are below; old GitHub links redirect to the new repository.

项目 / Item 旧 / Old 新 / New
产品名 / Product 复杂解压工具 v2 / Complex Unzip Tool v2 深度解压 / DeepUnzip
程序 / Executable complex-unzip-tool-v2.exe deepunzip.exe
发布包 / Release assets complex-unzip-tool-v2-v<版本>-<平台> deepunzip-v<版本>-<平台>
源码运行的命令 / Commands from source main、cuz deepunzip、dz
仓库 / Repository rozx/Complex-unzip-tool-v2 rozx/DeepUnzip

新功能 / New features

  • 分卷可以来自任何地方:散落在输入文件夹的不同子文件夹里,或者分别装在别的压缩包里,程序都会找齐再解压。查找从第一卷所在的文件夹开始,逐层向外扩大,最远到输入文件夹。

  • 压缩包里解出来的伪装文件名也会还原,例如 movie.7z.001删掉 还原为 movie.7z.001。

  • 新的终端输出:每处理完一个压缩包输出一行,实时显示整体进度和当前压缩包的进度;结束时用一棵来源树列出每个分卷来自哪个压缩包、原来叫什么名字,再给出摘要。输出被重定向时打印同样的内容,但没有动画。

  • 输出支持简体中文、繁体中文、英文、日文和韩文,默认跟随系统语言,可用环境变量 DEEPUNZIP_LANG(zh、zh-TW、en、ja、ko)指定。

  • --json:标准输出只写逐行的 JSON 事件,最后一行总是 summary,方便脚本读取;这一模式下不会询问任何问题。

  • 退出码:0 全部解开,1 有解不开的项目(对应的原文件已保留),2 无法运行(找不到 7-Zip、路径都不存在或程序出错)。

  • 程序换上了新图标:从纸箱里探出头的猫。

  • Volumes can come from anywhere: spread over subfolders of the input folder or packed inside other archives, they are gathered before extraction. The search starts in the folder of the first volume and widens outward, up to the input folder.

  • Disguised names of files extracted from archives are restored too, for example movie.7z.001删掉 becomes movie.7z.001.

  • New terminal output: one line per finished archive, live progress for the whole run and for the current archive, and at the end a lineage tree that shows which archive each volume came from and its original name, followed by a summary. Redirected output gets the same content without animation.

  • The output is available in Simplified Chinese, Traditional Chinese, English, Japanese and Korean. It follows the system language; set DEEPUNZIP_LANG (zh, zh-TW, en, ja, ko) to choose.

  • --json: standard output carries only JSON event lines, always ending with summary, for scripts. It never asks anything.

  • Exit codes: 0 everything extracted, 1 some items could not be extracted (their originals are kept), 2 could not run (7-Zip missing, no given path exists, or an error).

  • A new program icon: a cat peeking out of a cardboard box.

改进 / Improvements

  • 处理不了的东西不会丢:从压缩包里解出、但处理不了的东西(打不开或密码错误的内层压缩包、凑不齐的分卷)会放进 unzipped/,输入文件夹里原有的留在原处,结束时都会写明原因和位置。

  • 新学到的密码会让之前因密码失败的分卷组再试一次。

  • 同一组分卷里内容完全相同的重复分卷视为已使用,不会妨碍解压。

  • 标准输入不是终端时(例如计划任务或 < NUL)不再询问,按默认选择继续。

  • 输出中不会出现密码本身,只写「密码 #2」这样的序号。

  • Nothing is lost: anything extracted from an archive but not usable (an inner archive that won't open or has an unknown password, an incomplete set of volumes) goes to unzipped/, files already in the input folder stay where they are, and the end of the run says why and where for each.

  • A newly learned password retries the multipart sets that failed on a password.

  • Byte-identical duplicate volumes of a set count as used and don't block extraction.

  • When standard input is not a terminal (a scheduled task, < NUL), DeepUnzip no longer asks and takes the default.

  • The output never shows a password, only its position, such as "password #2".

修复 / Bug fixes

  • 修复了分卷分别装在不同压缩包里、且其中一卷名字被伪装时无法解压的问题。

  • 修复了单个分卷(例如只有 X.7z.001)被当成普通文件处理的问题。

  • Fixed sets whose volumes sit in different archives, one of them with a disguised name, failing to extract.

  • Fixed a lone volume (such as X.7z.001 on its own) being treated as a regular file.

下载 / Downloads

平台 / Platform 文件 / File
Windows x64 deepunzip-v2.0.0-windows-x64.zip
macOS Intel deepunzip-v2.0.0-macos-x64.tar.gz
macOS Apple Silicon deepunzip-v2.0.0-macos-arm64.tar.gz
Linux x64 deepunzip-v2.0.0-linux-x64.tar.gz
Linux ARM64 deepunzip-v2.0.0-linux-arm64.tar.gz

SHA256SUMS 列出各文件的校验和。 / SHA256SUMS lists the checksum of every file.

升级说明 / Upgrade notes

  • 程序和发布包改名为 deepunzip(见上方对照表)。从源码运行时,main 和 cuz 在 2.x 中仍可使用,但会提示改用 deepunzip 或 dz,将在 3.0.0 移除。

  • 多个输入路径位于不同文件夹时,每个文件夹各自输出到自己的 unzipped/;以前全部写到第一个路径的 unzipped/。

  • 原文件在整个运行结束后才统一删除,并且只删除解出内容全部处理成功的;解出内容为空的压缩包会保留原文件。输入文件夹里的普通文件不会被动。

  • 退出码有变化:有解不开的项目时,以前退出码是 0,现在是 1;找不到 7-Zip 时,以前是 1,现在是 2。

  • 输出不再中英并列,每次运行只用一种语言,跟随系统语言或 DEEPUNZIP_LANG。输出的措辞和排版都变了,解析旧输出文本的脚本请改用 --json。

  • 运行中断后,下次运行会自动把为拼合分卷而挪走的原始分卷放回原处;伪装文件名的还原仍会先询问。1.3.x 留下的 .unzip-rename-history.tmp.json 仍能识别和恢复。

  • 发布说明统一放在仓库的 docs/releaseNotes/v<版本>.md,GitHub Release 的正文直接取自该文件。

  • The program and release packages are renamed deepunzip (see the table above). When running from source, main and cuz still work in 2.x but print a notice to use deepunzip or dz; they are removed in 3.0.0.

  • With input paths in several folders, each folder gets its own unzipped/; previously everything went to the first path's unzipped/.

  • Originals are deleted together at the end of the run, and only when everything extracted from them succeeded; an archive that extracts to nothing keeps its original. Regular files in the input folder are never touched.

  • Exit codes changed: a run with items that could not be extracted used to exit 0 and now exits 1; a missing 7-Zip used to exit 1 and now exits 2.

  • The output is no longer English and Chinese side by side; each run uses one language, following the system or DEEPUNZIP_LANG. Wording and layout changed, so scripts that parsed the old text should use --json.

  • After an interrupted run, the next run puts source volumes that were moved for assembly back automatically; reverting disguised-name renames still asks first. .unzip-rename-history.tmp.json files left by 1.3.x are still recognized and recovered.

  • Release notes now live in the repository at docs/releaseNotes/v<version>.md, and the GitHub release text is taken from that file.

已知问题与待验收 / Known issues and pending verification

  • 日文和韩文的输出文字与 README 译文尚待母语者校对。

  • macOS 和 Linux 版本只经过发布流程中的自动构建和冒烟测试,尚未在实机上手动验收。

  • 程序没有代码签名,macOS 版也没有公证:Windows 可能显示 SmartScreen 提示,macOS 需要先执行 xattr -d com.apple.quarantine ./deepunzip。

  • The Japanese and Korean output texts and README translations still need a native-speaker review.

  • The macOS and Linux builds are only covered by the automated build and smoke tests of the release workflow; they have not been checked by hand on real machines.

  • The program is not code-signed and the macOS builds are not notarized: Windows may show a SmartScreen warning, and on macOS run xattr -d com.apple.quarantine ./deepunzip first.

v1.3.2

Choose a tag to compare

@github-actions github-actions released this 09 Oct 17:20
5285d0f

Release Notes v1.3.2 / 发布说明 v1.3.2

Version 1.3.2 fixes repeated password prompts when extracting multiple encrypted archives in one run.

1.3.2 修复了同一次运行中解压多个加密压缩包时,需要重复输入相同密码的问题。

Bug Fixes / 错误修复

Entered passwords are reused for later archives / 手动输入的密码会复用于后续压缩包 — #24

After a manually entered password successfully extracts an archive, later single and multipart archives in the same run automatically try it. This also covers passwords entered while extracting nested archives or retrying with an alternative archive in the group. Previously, a password learned in one group was unavailable to later groups in the same processing stage, so archives sharing a password required repeated input.

New passwords are still saved to the tool-directory passwords.txt when the run finishes, for reuse next time. Existing comments, blank lines and password order are preserved. Archives skipped because of a missing or incorrect password are still retained.

手动输入密码并成功解压后,工具会立即将该密码用于本次运行后续的单包和分卷。这也适用于嵌套解压和使用组内备用档案重试时输入的密码。此前,同一处理阶段中的后续档案无法使用刚学到的密码,导致使用相同密码的一批压缩包仍需逐个输入。

新密码仍在运行结束时保存到工具目录的 passwords.txt,供下次运行复用。已有注释、空行和密码顺序保持不变;因密码缺失或错误而跳过的压缩包仍会保留。

v1.3.1

Choose a tag to compare

@github-actions github-actions released this 26 Sep 16:53
bab0d85

Release Notes v1.3.1 / 发布说明 v1.3.1

Version 1.3.1 stops executables, documents and app packages inside archives from being unpacked and deleted, and makes nested-archive cleanup recoverable. It also adds # comments to passwords.txt, stops readme files and other non-archives from being reported as errors, and accepts command-line options after the input paths.

1.3.1 修复了档案内的可执行文件、文档和程序包被误解压并删除的问题,并让嵌套档案的清理可以恢复。同时支持在 passwords.txt 中使用 # 注释,说明文件等非档案不再报错,命令行选项也可以写在输入路径之后。

New Features / 新功能

Comments in passwords.txt / passwords.txt 支持注释 — #22

Lines starting with # are now comments and are not tried as passwords. When newly learned passwords are saved, they are appended to the existing file, so comments, blank lines and the original order are kept.

A password that really starts with # is written with a leading backslash: \#abc means the password #abc. Passwords learned during a run are escaped this way automatically. When upgrading, check passwords.txt for passwords that start with #: they are now read as comments until you add the backslash.

以 # 开头的行现在视为注释,不会被当作密码尝试。保存新学到的密码时会追加到原文件末尾,注释、空行和原有顺序均保持不变。

密码本身以 # 开头时,请在前面加反斜杠:\#abc 表示密码 #abc。运行中新学到的密码会自动按此方式转义。升级时请检查 passwords.txt 中是否有以 # 开头的密码:在加上反斜杠之前,它们会被当作注释。

Bug Fixes / 错误修复

Executables inside archives are no longer unpacked / 档案内的可执行文件不再被误解压 — #21

A file found inside an extracted archive is now extracted only when 7-Zip identifies it as a real container (7z, RAR, ZIP, TAR, gzip, CAB, ISO, …). Plain .exe/.dll files, which 7-Zip can open to list their PE sections, are now kept unchanged instead of becoming NAME.dll_2\ folders. The same applies to other formats 7-Zip merely opens, such as ELF/Mach-O binaries, .msi/.doc (Compound) files, NSIS installers and FLV videos. Self-extracting archives, where 7-Zip reports the embedded container, are still extracted.

Processed nested archives now follow the deletion mode: they go to the Recycle Bin by default and are deleted permanently only with --permanent-delete. If the Recycle Bin is unavailable, the nested archive is kept in the output folder instead of being deleted.

解压出的文件现在只有在 7-Zip 识别为真正的档案容器(7z、RAR、ZIP、TAR、gzip、CAB、ISO 等)时才会继续解压。普通 .exe/.dll 虽然能被 7-Zip 打开并列出 PE 节区,但现在会原样保留,不再变成 NAME.dll_2\ 目录。ELF/Mach-O 程序、.msi/.doc(Compound)文件、NSIS 安装包和 FLV 视频等 7-Zip 仅能“打开”的格式同样保留。7-Zip 能识别出内嵌容器的自解压包仍会正常解压。

已处理的嵌套档案现在遵循删除模式:默认移入回收站,只有使用 --permanent-delete 时才永久删除。回收站不可用时,嵌套档案会保留在输出目录中,而不会被删除。

Documents and app packages inside archives are kept intact / 档案内的文档和程序包保持完整

Office documents (.docx, .xlsx, .pptx), OpenDocument files (.odt, .ods, .odp), Apple iWork files (.pages, .numbers, .key), e-books (.epub) and app or extension packages (.jar, .apk, .ipa, .appx/.msix, .vsix, .xpi, .whl, …) are ZIP files underneath. They are now kept as regular files instead of being unpacked into their internal XML or class files. The same files found directly in an input folder are left in place with a "Kept document/package" notice and counted as skipped, not as errors. The name alone is not trusted: the file must be a ZIP that also contains the entry its format requires, such as [Content_Types].xml in a .docx or AndroidManifest.xml in an .apk. A plain ZIP renamed to a document name (for example 资源.zip.docx), a ZIP disguised as .jpg or .mp4, a 7z/RAR named .docx, and .cbz comic archives are still extracted. To unpack a real document on purpose, rename it to .zip.

Office 文档(.docx、.xlsx、.pptx)、OpenDocument 文件(.odt、.ods、.odp)、Apple iWork 文件(.pages、.numbers、.key)、电子书(.epub)以及应用或扩展程序包(.jar、.apk、.ipa、.appx/.msix、.vsix、.xpi、.whl 等)本质上是 ZIP 文件。现在它们会作为普通文件保留,不再被拆成内部的 XML 或 class 文件。直接位于输入目录中的此类文件也会原样保留,提示“保留文档/程序包”,并计入“跳过”而非错误。不会仅凭文件名判断:文件必须是 ZIP,且包含该格式必需的条目,例如 .docx 中的 [Content_Types].xml、.apk 中的 AndroidManifest.xml。改成文档名的普通 ZIP(如 资源.zip.docx)、伪装成 .jpg、.mp4 的 ZIP、以 .docx 命名的 7z/RAR,以及 .cbz 漫画档案仍会正常解压。如确需解开真正的文档,请将其改名为 .zip。

Readme and other non-archive files no longer reported as errors / 说明文件等非档案不再报错

Files next to the archives that are clearly not archives, such as a 请先看我.txt readme, .url shortcuts or cover images, are now skipped with an info line and kept in place. They no longer add "Failed to extract" / "File is not a valid archive" entries to the final summary, which now lists them as "skipped". A lone numbered file such as report.001, with no other volumes to join, is also kept as it is. A file that looks like an archive by name or signature but cannot be opened (for example a damaged .7z) is still reported as an error.

与档案放在一起、明显不是档案的文件(如 请先看我.txt 说明、.url 快捷方式、封面图片)现在会提示跳过并原样保留,不再在最终摘要中产生“提取失败”/“文件不是有效档案”错误,摘要中改为计入“跳过”。没有其他分卷可合并的单个编号文件(如 report.001)同样原样保留。按名称或文件签名看起来是档案但无法打开的文件(例如损坏的 .7z)仍会报告为错误。

Options work after input paths / 选项可写在输入路径之后

Options such as --permanent-delete are now recognized anywhere on the command line, including after the paths (for example complex-unzip-tool-v2 "D:\Downloads" --permanent-delete). Previously an option after a path was silently ignored and treated as another input path, which added bogus "archive not found" errors. An unknown option (for example a typo such as --permanant-delete) now stops with a "No such option" error instead of being treated as an input path. The version subcommand works again; --version is unchanged.

--permanent-delete 等选项现在可以写在命令行任意位置,包括输入路径之后(例如 complex-unzip-tool-v2 "D:\Downloads" --permanent-delete)。此前写在路径之后的选项会被静默忽略并被当作另一个输入路径,产生多余的“档案未找到”错误。未知选项(例如拼错的 --permanant-delete)现在会报“No such option”错误并停止,而不会被当作输入路径。version 子命令恢复可用,--version 不变。

v1.3.0

Choose a tag to compare

@github-actions github-actions released this 24 Sep 20:11
872709f

Release Notes v1.3.0 / 发布说明 v1.3.0

Version 1.3.0 adds native macOS and Linux support, updates the bundled 7-Zip to 26.03 on all platforms, and fixes password-book lookup, multipart cleanup, and redirected Windows output. It also introduces GitHub Actions builds and releases for five platform targets.

1.3.0 新增 macOS 和 Linux 原生支持,将各平台内置的 7-Zip 更新至 26.03,并修复密码本路径、分卷清理和 Windows 输出重定向问题。同时新增 GitHub Actions,为五个平台构建程序并自动发布。

Platform Support / 平台支持

Choose the package for your operating system and CPU architecture. Each package contains a standalone executable with Python and the native 7-Zip engine, plus documentation and licenses. No separate Python or 7-Zip installation is needed, and no engine is downloaded at runtime.

请按操作系统和 CPU 架构选择发布包。每个包包含内置 Python 和原生 7-Zip 引擎的独立程序,以及说明文档和许可证。无需另行安装 Python 或 7-Zip,运行时也不会联网下载引擎。

Platform / 平台 Package / 发布包
Windows x64 complex-unzip-tool-v2-v1.3.0-windows-x64.zip
macOS Intel complex-unzip-tool-v2-v1.3.0-macos-x64.tar.gz
macOS Apple Silicon complex-unzip-tool-v2-v1.3.0-macos-arm64.tar.gz
Linux x64 complex-unzip-tool-v2-v1.3.0-linux-x64.tar.gz
Linux ARM64 complex-unzip-tool-v2-v1.3.0-linux-arm64.tar.gz
  • Windows includes the updated 7z.exe and 7z.dll; macOS uses universal 7zz; Linux uses the matching static 7zzs. The macOS application itself has separate Intel and Apple Silicon builds.

  • Missing or unusable engines are reported before the CLI modifies input files. --help and --version remain available.

  • macOS and Linux programs exit without an extra Enter prompt. Windows only pauses when both input and output are interactive terminals.

  • Windows 内置更新后的 7z.exe 和 7z.dll;macOS 使用通用二进制 7zz;Linux 使用对应架构的静态 7zzs。macOS 应用本身仍分别提供 Intel 和 Apple Silicon 构建。

  • 引擎缺失或不可用时,会在修改输入文件前报错;--help 和 --version 仍可使用。

  • macOS 和 Linux 程序结束后直接退出;Windows 仅在输入、输出均为交互式终端时等待回车。

Bug Fixes / 错误修复

Password books follow the tool directory / 密码本固定使用工具目录 — #19

The global passwords.txt is now loaded and saved beside the executable, or at the project root when running from source. Launching from another working directory or dragging an archive onto the Windows executable no longer changes that location. The target-directory password book remains an additional read-only source, unless it is the same file as the global book.

If the global book cannot be saved, the CLI reports the path and write-permission problem and continues its final cleanup. Builds no longer embed a personal passwords.txt inside the executable.

全局 passwords.txt 现在固定在可执行文件旁读写;从源码运行时使用项目根目录。从其他工作目录启动,或将压缩包拖到 Windows 程序上,都不会改变这个位置。目标目录的密码本仍作为额外的只读来源,除非它与全局密码本是同一个文件。

全局密码本无法保存时,CLI 会提示路径和写入权限问题,并继续完成收尾。构建程序也不再内嵌个人 passwords.txt。

Single-file inputs include matching volumes / 单文件输入自动收集同组分卷 — #18

Passing only movie.7z.001 now discovers its matching sibling volumes before extraction, including cloaked names such as movie.7z.002删除. A cloaked primary is also recognized. Successful extraction cleans up the entire discovered set instead of leaving .002 and later parts behind. Discovery is limited to the same directory, archive name, and split convention; unrelated archives and subdirectories are excluded. Extraction or password failure still preserves all source parts.

只传入 movie.7z.001 时,现在会先收集同组分卷再解压,包括 movie.7z.002删除 等伪装续卷;传入伪装主卷同样可以识别。成功后统一清理已收集的整组源文件,不再遗留 .002 等续卷。收集范围限定为同目录、同名且采用同一分卷格式的文件,不包含无关档案和子目录。解压或密码失败时,仍会保留全部源分卷。

Redirected Windows output uses UTF-8 / Windows 重定向输出使用 UTF-8 — #17

Windows stdout and stderr redirected to a file or pipe are configured as UTF-8 before the first banner. Chinese text and emoji no longer trigger the reported GBK UnicodeEncodeError. Standalone builds also enable Python's UTF-8 mode, without depending on environment variables. Redirected output no longer waits for Enter at exit.

Windows 的 stdout 和 stderr 被重定向到文件或管道时,会在首次输出前设置为 UTF-8。中文和 emoji 不再触发此前的 GBK UnicodeEncodeError。独立构建同时启用 Python UTF-8 模式,无需依赖环境变量;输出重定向时,结束后也不会等待回车。

Build and Release Automation / 构建与自动发布

  • GitHub CI runs tests, engine checksum checks, real archive smoke tests, and standalone builds for all five platform targets.

  • Automatic publication requires a PR from release/*, carrying the release label at merge time, to be merged into main. The workflow builds the exact merge commit and publishes only after all platform builds and asset checks succeed.

  • Release descriptions come verbatim from ReleaseNotes/RELEASE_NOTES_vX.Y.Z.md. Missing or empty notes stop the release before platform builds begin.

  • Releases include the five packages and SHA256SUMS. Interrupted uploads can resume a matching draft; published releases are not overwritten.

  • GitHub CI 为五个平台执行测试、引擎校验、真实压缩包冒烟测试和独立程序构建。

  • 自动发布要求来源分支为 release/*,PR 在合并时带有 release 标签,并合并到 main。工作流使用确切的合并提交构建,所有平台构建及产物校验成功后才发布。

  • 发布说明直接采用 ReleaseNotes/RELEASE_NOTES_vX.Y.Z.md 的原文。文件缺失或为空时,会在平台构建开始前中止发布。

  • Release 包含五个平台的发布包和 SHA256SUMS。上传中断后可以继续匹配的草稿,已公开的版本不会被覆盖。

Upgrade Notes / 升级须知

  • Windows packaging: extract the .zip first, then run or drag files onto complex-unzip-tool-v2.exe. Keep your global passwords.txt beside the new executable.

  • Password migration: if an older version wrote passwords into a launch directory such as Desktop or Downloads, move or merge those entries into the tool-directory book. A book beside the input archive is still read for that input, but learned passwords are saved to the tool directory.

  • macOS / Linux: extract the matching .tar.gz and run ./complex-unzip-tool-v2 "archive directory" in a terminal. Preserve executable permissions.

  • Compatibility: Linux standalone packages are built on Ubuntu 24.04 and require compatible system libraries; the static 7-Zip engine does not make the entire application static. Windows publisher signing and macOS signing/notarization are not configured. Linux recycling requires a usable desktop trash directory; originals remain if recycling fails.

  • Windows 发布包: 先解开 .zip,再运行 complex-unzip-tool-v2.exe 或将文件拖到程序上。全局 passwords.txt 请保留在新程序旁。

  • 密码本迁移: 如果旧版本曾把密码写到桌面、下载目录等启动目录,请将这些条目移入或合并到工具目录的密码本。输入档案旁的密码本仍可用于该任务,但新学到的密码会写到工具目录。

  • macOS / Linux: 解开对应的 .tar.gz 后,在终端运行 ./complex-unzip-tool-v2 "待解压目录",并保留执行权限。

  • 兼容性: Linux 独立包在 Ubuntu 24.04 上构建,需要兼容的系统库;内置静态 7-Zip 不代表整个应用静态链接。Windows 发行者签名、macOS 签名及公证尚未配置。Linux 回收文件需要可用的桌面废纸篓目录;回收失败时保留原文件。

Validation / 验证

The 300-test suite passes locally on macOS ARM64. Source and standalone smoke tests passed with nested ZIPs, encrypted 7z archives, Unicode filenames/passwords, and both directory and single-file multipart inputs. Regression coverage includes GBK-encoded redirected streams, password-save failures, and source retention on extraction/password failure. Native builds for all five platforms are enforced by the release CI.

300 项测试已在本地 macOS ARM64 上通过。源码与独立程序均通过了嵌套 ZIP、加密 7z、中文文件名及密码、目录输入和单文件分卷输入的冒烟验证。回归测试覆盖 GBK 重定向输出、密码本保存失败,以及解压或密码失败时的源文件保留。五个平台的原生构建由发布 CI 检查。

v1.2.2

Choose a tag to compare

@rozx rozx released this 08 Jul 01:14

Release Notes v1.2.2 / 发布说明 v1.2.2

A focused patch release fixing two cloaked-file detection bugs — one false positive that could corrupt a valid archive into a bogus multipart set, and one false negative that left deeply-cloaked multipart sets unextractable — plus documentation restructuring with a new English README. No breaking changes.

一个聚焦的补丁版本,修复了两个伪装文件检测问题 —— 一个是把有效档案误切成伪造多卷集合的误报,另一个是导致深度伪装的多卷集合无法解压的漏报 —— 并重构了文档、新增英文 README。无破坏性更改。

🐛 Bug Fixes / 错误修复

Don't split a valid archive into a bogus multipart part / 不再把有效档案切成伪造的多卷分卷

A lone file that already carries a real archive signature — e.g. an SFX (MZ / PE) archive named jk_20260629_192705 — could be sliced into a fake multipart part jk_20260629_192.7z.705. The trailing 705 of an HHMMSS timestamp was mistaken for a 7z part number, so a perfectly valid whole archive was renamed into a broken "part" that would never extract.

Root cause: _verify_with_signature() never used its part_number argument, so any guessed part number was accepted as long as some signature was present.

Fix: _verify_with_signature() now uses part_number. A signature-bearing lone file can only be a whole archive or the first volume (.001), so any other guessed part number (.705, .382, …) is refused. Genuine cloaked first parts still uncloak correctly.

一个本身带有真实档案签名的独立文件 —— 例如名为 jk_20260629_192705 的自解压(MZ / PE)档案 —— 原先可能被切成伪造的多卷分卷 jk_20260629_192.7z.705。HHMMSS 时间戳末尾的 705 被误当成 7z 分卷编号,于是一个完好的整档被改名成了永远无法解压的残缺"分卷"。

根因:_verify_with_signature() 从未使用它的 part_number 参数,只要存在任意签名,任何猜测出来的分卷编号都会被接受。

修复:_verify_with_signature() 现在会使用 part_number。带签名的独立文件只可能是整档或首卷(.001),因此任何其他猜测出的分卷编号(.705、.382 等)都会被拒绝。真正的伪装首卷仍能正确还原。

Recover multipart parts with cloaking embedded inside the extension / 还原扩展名内部被插入伪装字符的多卷分卷

Cloaking characters embedded inside the extension or the part digits — such as 12.7z.0删02 or 1.part2.r删ar — could not be matched by the flat rename rules, which only strip trailing garbage. Those parts stayed cloaked, so the multipart set was incomplete and could not be extracted.

Fix: added uncloak_archive_filename, which reuses the flexible archive-name reconstructor as a fallback. It fires only when the rebuilt name is an unambiguous multipart/volume form (e.g. 12.7z.002, 1.part2.rar), so ordinary files are never renamed into bogus parts.

被插入到扩展名或分卷数字内部的伪装字符 —— 例如 12.7z.0删02 或 1.part2.r删ar —— 无法被只能去除尾部垃圾的扁平改名规则匹配。这些分卷保持伪装状态,导致多卷集合不完整、无法解压。

修复:新增 uncloak_archive_filename,复用灵活的档案名重建器作为回退方案。它仅在重建出的名字是明确的多卷/分卷形式(例如 12.7z.002、1.part2.rar)时才生效,因此普通文件绝不会被改名成伪造的分卷。

Safety boundary preserved / 安全边界不变

The stricter checks do not weaken existing behavior: a genuine cloaked first part (secret001 with real magic bytes) still uncloaks to secret.7z.001, while non-archive files are left exactly as they are — 2382 is not renamed into 2.7z.382, and chapter.part2.data (a .data file that merely contains part2) is not renamed into a .rar part.

更严格的检查不会削弱已有行为:真正的伪装首卷(带真实魔数的 secret001)仍会还原为 secret.7z.001;而非档案文件保持原样 —— 2382 不会被改名成 2.7z.382,chapter.part2.data(仅名字里含 part2 的 .data 文件)也不会被改名成 .rar 分卷。

📖 Documentation / 文档

English README + restructured docs / 新增英文 README 并重构文档

Added a standalone English README.en.md and restructured the main README.md so both language versions stay in sync and are easier to navigate.

新增独立的英文 README.en.md,并重构主 README.md,使中英文两个版本保持同步、更易浏览。

✅ Test Coverage / 测试覆盖

New/Updated Tests / 新增/更新测试

  • Signature false positive (test_signature_bearing_file_with_timestamp_suffix_not_split): a signature-bearing lone file whose name ends in a timestamp is not sliced into a fake .7z.705 part.
  • Embedded-garbage recovery (TestCloakedEmbeddedGarbage): 12.7z.0删02 uncloaks to 12.7z.002, while a non-archive chapter.part2.data that merely contains the word part2 is left untouched.

Total: 207 tests pass (was 199 in v1.2.1, +8 new).

  • 签名误报(test_signature_bearing_file_with_timestamp_suffix_not_split):名字以时间戳结尾且带签名的独立文件不会被切成伪造的 .7z.705 分卷。
  • 内部伪装还原(TestCloakedEmbeddedGarbage):12.7z.0删02 还原为 12.7z.002,而仅名字里含 part2 的非档案 chapter.part2.data 保持原样。

总计:207 个测试通过(v1.2.1 是 199 个,新增 8 个)。

🚀 Migration Notes / 迁移说明

For Users / 用户须知

  • No breaking changes.

  • Whole archives whose names end in a timestamp or trailing digits (e.g. an SFX file jk_20260629_192705) are no longer mis-split into broken parts, so they extract correctly.

  • Multipart sets whose parts had cloaking characters buried inside the extension (e.g. 12.7z.0删02) are now recovered and extracted instead of being left behind.

  • 无破坏性更改。

  • 名字以时间戳或尾部数字结尾的整档(例如自解压文件 jk_20260629_192705)不再被误切成残缺分卷,能够正确解压。

  • 分卷的扩展名内部藏有伪装字符的多卷集合(例如 12.7z.0删02)现在会被还原并解压,而不再被遗留。

Full Changelog: v1.2.1...v1.2.2

V1.2.1

Choose a tag to compare

@rozx rozx released this 07 Jun 05:19
b0085cc

Release Notes v1.2.1 / 发布说明 v1.2.1

A focused patch release fixing two data-loss bugs in cloaked-file detection and archive grouping, and expanding multi-part archive format detection to all archive types. No breaking changes.

一个聚焦的补丁版本,修复了伪装文件检测和档案分组中的两个数据丢失问题,并将多卷档案格式识别扩展到所有档案类型。无破坏性更改。

🐛 Bug Fixes / 错误修复

Don't rename ordinary files into bogus archive parts / 不再把普通文件改名成伪造的档案分卷

A plain non-archive file whose name ends in digits (e.g. 2382) could be renamed into a fake 7z multipart part (2.7z.382). It was then swept into a same-named real archive set and deleted at the end without ever being extracted — losing the user's data.

Root cause: _verify_with_signature() always returned True, so the weak extensionless/digit-suffix cloaking rules renamed any digit-suffixed file.

The signature gate now distinguishes deliberate cloaking from a guess:

  • If the name carries an explicit archive token (.7z / .rar / .zip, via ARCHIVE_TOKEN_RE), the rename is trusted — continuation parts legitimately have no signature (e.g. something.7z.002删除).
  • If the type was only guessed from a trailing number, a real magic-byte signature is now required before renaming.
  • On verification error the tool is now conservative and skips the rename instead of assuming the file is valid.

Genuine cloaked first parts and .7z.00N删 style parts still uncloak correctly.

名字以数字结尾的普通(非档案)文件(例如 2382)原先可能被改名成伪造的 7z 分卷(2.7z.382),随后被并入同名的真实档案集合,在结尾被删除却从未解压 —— 导致用户数据丢失。

根因:_verify_with_signature() 永远返回 True,导致弱规则(无扩展名 / 尾部数字)会改名任何带数字后缀的文件。

签名校验现在区分"有意伪装"与"猜测":

  • 名字中带有显式档案标记(.7z / .rar / .zip,由 ARCHIVE_TOKEN_RE 识别)时,信任改名 —— 续卷本来就没有签名(例如 something.7z.002删除)。
  • 若类型只是从尾部数字猜测得到,改名前现在必须有真实的魔数签名。
  • 校验出错时改为保守处理,跳过改名,而不是假定文件有效。

真正的伪装首卷以及 .7z.00N删 之类的分卷仍能正确还原。

Don't merge different archive types that share a base name / 不再合并同名但类型不同的档案

The similarity check in _should_group_files ignored the archive extension, so a standalone .7z could be swept into a spanned .zip / .z01 group when they shared a base name and directory. The merged multipart group then deleted the .7z along with the zip parts (data loss) and mishandled the set during extraction.

Fix: the similarity path now requires ext1 == ext2, so only same-family archives group that way. .zip / .z01 still group via the exact (base, ext) check, and foo.7z stays its own single group alongside the foo.zip / foo.z01 set.

_should_group_files 的相似度判断忽略了档案扩展名,导致独立的 .7z 在与跨卷 .zip / .z01 同名且同目录时被并入同一组。合并后的多卷组随后把 .7z 连同 zip 分卷一起删除(数据丢失),解压时也处理错误。

修复:相似度路径现在要求 ext1 == ext2,只有同家族档案才走该路径分组。.zip / .z01 仍通过精确的 (base, ext) 判断分组,而 foo.7z 与 foo.zip / foo.z01 集合并存时保持为独立的单档案组。

✨ Improvements / 功能增强

Expanded multi-part archive format detection / 扩展多卷档案格式识别

Multi-part sets across all archive types are now recognized into a single group with the correct primary as the extraction entry point (previously only .7z.001, .tar.*.001, .zip/.z01, .rar/.r00/.partN.rar were handled correctly):

  • 7-Zip generic numbered split for any base extension — name.<ext>.001 / .002 … (zero-padded, 3+ digits), with .001 as the entry point. This covers the common name.zip.001 (produced by 7-Zip's "Split file") as well as name.rar.001, name.iso.001, and any other <ext>. Previously these were split into wrong groups or treated as single archives, leaving continuation parts behind.
  • WinZip ZIPX split — name.zipx + name.zx01 / .zx02 … (primary .zipx).
  • ARJ multi-volume — name.arj + name.a01 / .a02 … (primary .arj).
  • ACE multi-volume — name.ace + name.c00 / .c01 … (primary .ace). Note: ACE sets are now grouped/classified correctly, but the bundled 7-Zip cannot decode ACE, so extraction still fails and the source parts are retained (never deleted).

Safety is unchanged: source files are deleted only after a successful extraction, so an ordinary numbered file that is not actually an archive (e.g. report.2024.001) is retained when extraction fails.

现在所有档案类型的多卷集合都会被识别为单个分组,并以正确的主卷作为解压入口(此前仅 .7z.001、.tar.*.001、.zip/.z01、.rar/.r00/.partN.rar 能被正确处理):

  • 任意扩展名的 7-Zip 通用编号分卷 —— name.<ext>.001 / .002 …(补零、3 位及以上),以 .001 为入口。覆盖常见的 name.zip.001(7-Zip"拆分文件"生成)以及 name.rar.001、name.iso.001 等任意 <ext>。此前这些会被分到错误的组或当成单个档案,导致续卷被遗留。
  • WinZip ZIPX 分卷 —— name.zipx + name.zx01 / .zx02 …(主卷 .zipx)。
  • ARJ 多卷 —— name.arj + name.a01 / .a02 …(主卷 .arj)。
  • ACE 多卷 —— name.ace + name.c00 / .c01 …(主卷 .ace)。注意: ACE 集合现在能被正确分组/识别,但捆绑的 7-Zip 无法解码 ACE,因此解压仍会失败,且源分卷会被保留(绝不删除)。

安全策略不变:仅在解压成功后才删除源文件,所以并非真正档案的编号文件(例如 report.2024.001)在解压失败时会被保留。

✅ Test Coverage / 测试覆盖

New/Updated Tests / 新增/更新测试

  • Cloaked false-positives (TestCloakedFalsePositives): a plain 2382 file is not detected/renamed, uncloak_file leaves a non-archive digit-suffixed file untouched, and a genuine cloaked 7z first part (real magic bytes) still uncloaks to secret.7z.001. Two existing _verify_with_signature tests were updated to pin the stricter behavior.
  • Grouping guard: unit (_should_group_files) regression that foo.7z vs foo.zip are not grouped, plus an integration (create_groups_by_name) regression asserting foo.7z stays a standalone group while foo.zip / .z01 / .z02 form one spanned set.
  • Multi-part format detection: a new test_regex.py for the pattern catalog, plus get_archive_base_name, _entry_point_priority, create_groups_by_name, nested-continuation, and ensure_contained_multipart_groups cases for the generic numbered split and ZIPX/ARJ/ACE formats.

Total: 199 tests pass (was 163 in v1.2.0, +36 new).

  • 伪装误报(TestCloakedFalsePositives):普通的 2382 文件不会被检测/改名;uncloak_file 对非档案的数字后缀文件保持原样;而真正的伪装 7z 首卷(带真实魔数)仍会还原为 secret.7z.001。两个原有的 _verify_with_signature 测试更新为锁定更严格的行为。
  • 分组守卫:单元测试(_should_group_files)回归确认 foo.7z 与 foo.zip 不被分到一组;集成测试(create_groups_by_name)回归确认 foo.7z 保持独立组,而 foo.zip / .z01 / .z02 组成一个跨卷集合。
  • 多卷格式识别:新增 test_regex.py 覆盖模式表,以及 get_archive_base_name、_entry_point_priority、create_groups_by_name、嵌套续卷、ensure_contained_multipart_groups 针对通用编号分卷与 ZIPX/ARJ/ACE 格式的用例。

总计:199 个测试通过(v1.2.0 是 163 个,新增 36 个)。

🚀 Migration Notes / 迁移说明

For Users / 用户须知

  • No breaking changes.

  • Ordinary files whose names happen to end in digits (e.g. 2382) are no longer mistaken for archive parts, renamed, or deleted — they are left exactly as they are.

  • A standalone .7z that shares a base name with a spanned .zip set is now extracted on its own instead of being deleted with the zip parts.

  • 无破坏性更改。

  • 名字恰好以数字结尾的普通文件(例如 2382)不再被误认为档案分卷、被改名或被删除 —— 它们保持原样。

  • 与跨卷 .zip 集合同名的独立 .7z 现在会被单独解压,而不会随 zip 分卷一起被删除。

What's Changed

Full Changelog: v1.2.0...v1.2.1

V1.2.0

Choose a tag to compare

@rozx rozx released this 28 Apr 01:44
29d7cfc

Release Notes v1.2.0 / 发布说明 v1.2.0

🎉 What's New / 新功能

Rename History with Revert-on-Failure / 重命名历史与失败回滚

The cloaked-file detector renames source files in-place (e.g. 1525.zip(1).001 → 1525.7z.001) before extraction begins. Previously, when extraction later failed (wrong password, corruption, missing volume, crash), users were left with files whose names no longer matched what they originally downloaded — making manual recovery difficult.

This release introduces a RenameHistory system that:

  • Tracks every successful uncloak rename to a JSON file in the input directory.
  • Binds each rename to its owning archive group after grouping.
  • Reverts the renames for any group whose extraction is preserved (failed / password-skipped / exception).
  • Clears the history for any group whose originals are deleted (success path).
  • Survives crashes: if the program is killed mid-run, the JSON file is left on disk; the next run detects it and offers [y/N] recovery.

伪装文件检测器在解压开始之前会就地重命名源文件(例如 1525.zip(1).001 → 1525.7z.001)。之前如果之后解压失败(密码错、损坏、分卷缺失、崩溃),用户面对的就是被改过名的文件,无法识别原始文件——手动恢复非常困难。

本版本引入 RenameHistory 系统:

  • 每次成功 uncloak 改名都记录到输入目录下的 JSON 文件。
  • 分组后将每条改名绑定到对应档案组。
  • 对任何保留原档的组(失败 / 密码跳过 / 异常)—— 回滚改名。
  • 对任何删除原档的组(成功路径)—— 清除历史条目。
  • 崩溃可恢复:程序中途被杀,JSON 文件留在磁盘上;下次运行检测到并提示 [y/N] 恢复。

Log examples / 日志示例:

⚠ Reverted 3 rename(s) for testDir-1525 已回滚 3 个改名:
    1525.7z.001 → 1525.zip(1).001
    ...
⚠ Detected pending rename history from a previous run
   检测到上次运行遗留的改名记录: 5 entries

🐛 Bug Fixes / 错误修复

Spanned ZIP / Volume RAR Multipart Grouping / 跨卷 ZIP 与多卷 RAR 分组

Spanned ZIP sets (.zip + .z01 + .z02) and volume RAR sets (.rar + .r00 + .r01) were being grouped inconsistently and the main archive was set to the continuation part (.z01 / .r00), causing 7-Zip to fail because extraction must be invoked on the .zip / .rar entry point.

Three root causes fixed:

  • get_archive_base_name now maps continuation suffixes (.zNN, .rNN, .partN.rar) to their family extension (zip / rar), so all parts of a set share the same (base, ext) tuple and are properly grouped.
  • MULTI_PART_PATTERNS in const.py now includes .partN.rar, .rNN, .zNN patterns.
  • ArchiveGroup.add_file now selects the main archive by entry-point priority (.7z.001 / .partN.rar = 100, .zip / .rar = 90, continuations = 0) regardless of insertion order. This guarantees the spanned .zip (not .z01) and volume .rar (not .r00) are always the main archive, so 7-Zip is invoked on the correct entry point.

跨卷 ZIP 集合(.zip + .z01 + .z02)和多卷 RAR 集合(.rar + .r00 + .r01)原先分组不一致,主档案会被设成续卷(.z01 / .r00),导致 7-Zip 失败 —— 因为提取必须从 .zip / .rar 入口开始。

修复了三个根因:

  • get_archive_base_name 把续卷后缀(.zNN、.rNN、.partN.rar)映射到家族扩展名(zip / rar),让同一集合所有分卷共享相同的 (base, ext),正确归组。
  • MULTI_PART_PATTERNS 增加 .partN.rar、.rNN、.zNN 模式。
  • ArchiveGroup.add_file 按"入口点优先级"选主档案(.7z.001 / .partN.rar = 100,.zip / .rar = 90,续卷 = 0),无论加入顺序,跨卷 .zip(不是 .z01)和多卷 .rar(不是 .r00)总是作为主档案,确保 7-Zip 调用正确入口。

✅ Test Coverage / 测试覆盖

New/Updated Tests / 新增/更新测试

  • 24 unit tests for RenameHistory: record/bind/revert/clear/finalize/load_pending, atomic write, collision-safe revert.
  • 4 integration tests in test_main.py: revert-on-failure, clear-on-success, recovery prompt accept (y), recovery prompt decline (n).
  • 13 regression tests for spanned ZIP / volume RAR grouping covering family extension mapping, ordered main-archive selection, and end-to-end create_groups_by_name scenarios.

Total: 163 tests pass (was 122 in v1.1.11, +41 new).

  • RenameHistory 的 24 个单元测试:record/bind/revert/clear/finalize/load_pending、原子写入、冲突安全回滚。
  • test_main.py 的 4 个集成测试:失败回滚、成功清除、恢复提示接受 y、恢复提示拒绝 n。
  • 跨卷 ZIP / 多卷 RAR 分组的 13 个回归测试,覆盖家族扩展名映射、有序主档案选择、create_groups_by_name 端到端场景。

总计:163 个测试通过(v1.1.11 是 122 个,新增 41 个)。

🚀 Migration Notes / 迁移说明

For Users / 用户须知

  • No breaking changes.

  • A new file .unzip-rename-history.tmp.json may appear in your input directory only while a run is in progress. It is automatically deleted when the run completes cleanly. If you see it after a crash or Ctrl+C, the next run will offer to revert pending renames; you can also delete it manually.

  • Spanned ZIP / volume RAR sets that previously failed due to wrong main-archive selection should now extract correctly without manual intervention.

  • If a group fails to extract, you'll see a Reverted N rename(s) message and the source files will be back to their original cloaked names — making manual recovery straightforward.

  • 无破坏性更改。

  • 输入目录中只在运行过程中可能出现新文件 .unzip-rename-history.tmp.json,正常完成时自动删除。如果在崩溃或 Ctrl+C 后看到它,下次运行会提示是否回滚待恢复的改名;你也可以手动删除。

  • 之前因主档案选错而失败的跨卷 ZIP / 多卷 RAR 集合,现在应当无需手动介入即可正确解压。

  • 若某组提取失败,会看到 Reverted N rename(s) 信息,源文件被恢复为原始的伪装名 —— 手动处理更直观。

What's Changed

  • V1.2.0 rename history and bug fixes by @rozx in #15

Full Changelog: v1.1.11...v1.2.0

V1.1.11

Choose a tag to compare

@rozx rozx released this 01 Feb 03:39
a163ca5

Release Notes v1.1.11 / 发布说明 v1.1.11

🎉 What's New / 新功能

Output Path Normalization / 输出路径规范化

Extracted output now flattens meaningless leading folders (typically numeric/symbol-only wrapper directories) while preserving meaningful structure.

提取输出现在会扁平化“无意义的前置文件夹”(通常为纯数字/符号的包裹目录),同时保留有意义的目录结构。

Examples / 示例:

  • 1/aaa.jpg → aaa.jpg
  • 1/5555+/222.jpg → 222.jpg

Auto-group Contained Multipart Sets / 自动分组容器内分卷集合

When a container archive extracts a multipart set into the output folder (e.g., .7z.001, .part1.rar, spanned .zip/.z01), the tool now auto-creates a multipart group so it can be extracted in the same run.

当容器档案在输出目录中解出分卷集合(例如 .7z.001、.part1.rar、跨卷 .zip/.z01)时,工具现在会自动创建分卷组,以便同一次运行中继续提取。

🐛 Bug Fixes / 错误修复

Prevent Source Multipart Deletion on Failure / 提取失败时不再删除源分卷

Multipart extraction failures (missing volumes, wrong password, etc.) no longer risk deleting the original multipart parts. The tool cleans up only tool-created temporary folders and keeps the source volumes for safe retry.

分卷提取失败(缺少分卷、密码错误等)时,不再有误删源分卷的风险。工具仅清理其创建的临时目录,并保留源分卷,便于安全重试。

Log / 日志:

  • Retained source multipart parts due to extraction failure 提取失败,保留源分卷

Cloaked Rename Collision Handling / 伪装文件重命名冲突处理

If cloaked normalization would rename two different files to the same target name, the tool now resolves the collision by renaming the duplicate to a unique __duplicate_<token> name (multipart-aware), preventing extraction failures and preserving sets.

如果“伪装文件规范化”会将两个不同文件重命名为同一个目标名,工具现在会将重复项改名为唯一的 __duplicate_<token>(兼容分卷后缀),从而避免提取失败并保留完整集合。

🔧 Improvements / 改进

Better Nested Multipart Robustness / 更稳健的嵌套分卷处理

  • During nested extraction, multipart continuation parts are tracked as candidates.

  • If a nested multipart primary fails (non-password failure), the tool attempts to locate/move matching continuation parts next to the primary and retries once.

  • If it still fails, the tool preserves the primary and gathered parts as outputs for later manual retry.

  • 嵌套提取过程中,会将续卷分卷记录为候选。

  • 若嵌套分卷主卷提取失败(非密码失败),工具会尝试查找/移动对应续卷到主卷旁边并重试一次。

  • 若仍失败,会保留主卷及已收集分卷到输出中,便于后续手动重试。

✅ Test Coverage / 测试覆盖

New/Updated Tests / 新增/更新测试

  • Output path normalization rules (flatten only meaningless leading folders)

  • Multipart retention guardrails on failure

  • Contained multipart discovery and grouping behavior

  • Cloaked rename collision scenarios

  • 输出路径规范化规则(仅扁平化“前置无意义”目录)

  • 分卷失败保留的保护逻辑

  • 容器内分卷发现与分组行为

  • 伪装重命名冲突场景

🚀 Migration Notes / 迁移说明

For Users / 用户须知

  • No breaking changes.

  • Output folder layout may be flatter if the archive contains meaningless wrapper directories.

  • Multipart failures are now safer: source parts are retained for retry.

  • 无破坏性更改。

  • 若档案包含无意义包裹目录,输出目录结构可能更扁平。

  • 分卷失败更安全:源分卷会被保留以便重试。

What's Changed

Full Changelog: v1.1.10...v1.1.11

v1.1.10

Choose a tag to compare

@rozx rozx released this 08 Jan 01:18
b98f4a3

Release Notes v1.1.10 / 发布说明 v1.1.10

🎉 What's New / 新功能

Enhanced Retry Extraction with User Passwords / 增强的重试提取与用户密码支持

The tool now supports a comprehensive retry extraction mechanism that can handle user-provided passwords and intelligently manage extraction results.

工具现在支持全面的重试提取机制,可以处理用户提供的密码并智能管理提取结果。

Highlights / 亮点:

  • User-provided passwords are now supported during retry extraction attempts.

  • Extracted files from retry operations are automatically moved to the output folder with progress tracking.

  • Original archives are preserved when extraction fails due to password issues.

  • Temporary folders are cleaned up after extraction attempts.

  • 重试提取期间现在支持用户提供的密码。

  • 重试操作的提取文件会自动移动到输出文件夹,并带有进度跟踪。

  • 当由于密码问题导致提取失败时,原始档案会被保留。

  • 提取尝试后临时文件夹会被清理。

Improved Nested Archive Preservation / 改进的嵌套档案保留

When nested archive extraction fails due to password issues, the tool now intelligently preserves the original nested archives instead of deleting them, allowing users to retry with correct passwords later.

当嵌套档案提取由于密码问题失败时,工具现在会智能地保留原始嵌套档案而不是删除它们,允许用户稍后使用正确的密码重试。

🐛 Bug Fixes / 错误修复

1. Fixed Incomplete Error Reporting / 修复不完整的错误报告

Issue / 问题: Error summaries were limited to showing only the first few errors, making it difficult to diagnose issues when multiple archives failed.

错误摘要仅显示前几个错误,使得在多个档案失败时难以诊断问题。

Fix / 修复: Updated error reporting functions to display all encountered errors without limiting the output, providing complete diagnostic information.

更新了错误报告函数,显示所有遇到的错误而不限制输出,提供完整的诊断信息。

Affected functions / 受影响的函数:

  • print_final_completion() - Now shows all completion errors
  • print_error_summary() - Now displays all error details

2. Enhanced Archive Deletion Logic / 增强的档案删除逻辑

Issue / 问题: Original archives were sometimes deleted even when extraction failed due to password issues, making it impossible to retry.

即使由于密码问题导致提取失败,原始档案有时也会被删除,使得无法重试。

Fix / 修复: Added intelligent logic to determine whether original archives should be deleted based on extraction results. Archives are now preserved when extraction fails due to password authentication issues.

添加了智能逻辑,根据提取结果确定是否应删除原始档案。当由于密码身份验证问题导致提取失败时,档案现在会被保留。

🔧 Improvements / 改进

Comprehensive Password Handling / 全面的密码处理

  • Passwords from both destination folder and tool root directory are now combined automatically.

  • User-provided passwords during retry extraction are properly tracked and used.

  • Better error messages when password authentication fails.

  • 目标文件夹和工具根目录的密码现在会自动合并。

  • 重试提取期间的用户提供的密码会被正确跟踪和使用。

  • 密码身份验证失败时提供更好的错误消息。

Enhanced Error Diagnostics / 增强的错误诊断

  • Archive extraction functions now consider both stdout and stderr for comprehensive error detection.

  • More detailed error information helps users understand why extraction failed.

  • 档案提取函数现在考虑 stdout 和 stderr 以进行全面的错误检测。

  • 更详细的错误信息帮助用户理解提取失败的原因。

Improved Cleanup Process / 改进的清理过程

  • Temporary folders created during extraction are now cleaned up more reliably.

  • Files from retry operations are properly moved to the output folder with progress feedback.

  • 提取期间创建的临时文件夹现在更可靠地被清理。

  • 重试操作的文件会正确移动到输出文件夹,并带有进度反馈。

📝 Documentation Updates / 文档更新

README.md Enhancements / README.md 增强内容

  • Expanded password file handling section with multiple search locations.

  • Clarified how passwords from different locations are combined.

  • Updated examples to reflect the new password handling capabilities.

  • 扩展了密码文件处理部分,包含多个搜索位置。

  • 阐明了不同位置的密码如何合并。

  • 更新了示例以反映新的密码处理功能。

Key additions / 主要新增内容:

  • Passwords can now be placed in both destination folder and tool root directory.

  • All found password files are combined automatically.

  • Clear examples showing password file placement.

  • 密码现在可以放在目标文件夹和工具根目录中。

  • 所有找到的密码文件会自动合并。

  • 清晰的示例显示密码文件的放置位置。

✅ Test Coverage / 测试覆盖

New Tests / 新增测试

  • Added tests for retry extraction with user-provided passwords.

  • Tests for archive preservation logic when extraction fails.

  • Enhanced error reporting tests to verify all errors are displayed.

  • Tests for temporary folder cleanup after extraction attempts.

  • 添加了使用用户提供的密码进行重试提取的测试。

  • 提取失败时档案保留逻辑的测试。

  • 增强的错误报告测试,验证显示所有错误。

  • 提取尝试后临时文件夹清理的测试。

Validation / 验证

  • ✅ All existing tests continue to pass

  • ✅ New retry extraction functionality tested with various password scenarios

  • ✅ Error reporting verified to show all encountered errors

  • ✅ Archive preservation logic tested with password failures

  • ✅ 所有现有测试继续通过

  • ✅ 新的重试提取功能在各种密码场景下进行了测试

  • ✅ 错误报告经验证显示所有遇到的错误

  • ✅ 档案保留逻辑在密码失败情况下进行了测试

⚙️ Technical Details / 技术细节

Modified Files / 修改的文件

complex_unzip_tool_v2/main.py

  • Added retry extraction logic with user password support (189 lines added)

  • Implemented file movement from retry results to output folder

  • Added intelligent archive deletion logic based on extraction results

  • Enhanced error handling for nested archive extraction

  • Added temporary folder cleanup after extraction attempts

  • 添加了带有用户密码支持的重试提取逻辑(新增 189 行)

  • 实现了从重试结果到输出文件夹的文件移动

  • 添加了基于提取结果的智能档案删除逻辑

  • 增强了嵌套档案提取的错误处理

  • 添加了提取尝试后的临时文件夹清理

complex_unzip_tool_v2/modules/archive_utils.py

  • Enhanced error handling to consider both stdout and stderr

  • Improved diagnostic information for archive extraction failures

  • Better support for password-related error detection

  • 增强了错误处理,考虑 stdout 和 stderr

  • 改进了档案提取失败的诊断信息

  • 更好地支持密码相关错误检测

complex_unzip_tool_v2/modules/rich_utils.py

  • Updated print_final_completion() to show all errors

  • Updated print_error_summary() to display complete error information

  • Removed conditional messages that limited error display

  • 更新了 print_final_completion() 以显示所有错误

  • 更新了 print_error_summary() 以显示完整的错误信息

  • 删除了限制错误显示的条件消息

README.md

  • Expanded password management section with multiple location support

  • Added clear examples for password file placement

  • Updated usage examples to reflect new capabilities

  • 扩展了密码管理部分,支持多个位置

  • 添加了密码文件放置的清晰示例

  • 更新了使用示例以反映新功能

Test Files / 测试文件

  • tests/test_archive_utils.py - Added 43 lines of new tests
  • tests/test_main.py - Added 15 lines of new tests

Code Statistics / 代码统计

  • Total changes / 总更改: 403 insertions(+), 93 deletions(-)
  • Files modified / 修改的文件: 9 files
  • Test additions / 测试新增: 58 lines of new tests

🚀 Migration Notes / 迁移说明

For Users / 用户须知

No breaking changes. All existing functionality is preserved and enhanced.

无破坏性更改。 所有现有功能都被保留和增强。

New benefits / 新优势:

  • More reliable extraction when password issues occur

  • Complete error information for better troubleshooting

  • Automatic cleanup of temporary files

  • Better handling of nested archives with password protection

  • 当出现密码问题时提取更可靠

  • 完整的错误信息以便更好地排除故障

  • 自动清理临时文件

  • 更好地处理受密码保护的嵌套档案

For Developers / 开发者须知

API Changes / API 更改:

  • Error reporting functions now display all errors by default (no longer limited)

  • Archive extraction error handling now considers both stdout and stderr

  • New helper function added for determining archive deletion logic

  • 错误报告函数现在默认显示所有错误(不再受限)

  • 档案提取错误处理现在考虑 stdout 和 stderr

  • 添加了用于确定档案删除逻辑的新辅助函数

If you maintain custom code / 如果您维护自定义代码:

  • Review error handling logic if you relied on limited error display

  • Update any custom extraction flows to handle the new retry mechanism

  • Consider the new archive preservation behavior in your workflows

  • 如果您依赖受限的错误显示,请审查错误处理逻辑

  • 更新任何自定义提取流程以处理新的重试机制

  • 在您的工作流程中考虑新的档案保留行为

🎯 Performance Impact / 性能影响

  • Retry extraction / 重试提取: Minimal overhead, only triggered when needed

  • Error reporting / 错误报告: Slightly increased output for comprehensive diagnostics

  • Cleanup operations / 清理操作: Improved efficiency with better temporary folder management

  • 重试提取: 最小开销,仅在需要时触发

  • 错误报告: 输出略微增加,以提供全面的诊断

  • 清理操作: 通过更好的临时文件夹管理提高了效率

🙏 Acknowledgments / 致谢

Special thanks to all users who provided feedback on password handling and error reporting!

特别感谢所有就密码处理和错误报告提供反馈的用户!


Full Changelog: v1.1.8...v1.1.10

完整变更日志: v1.1.8...v1.1.10

What's Changed

Full Changelog: v1.1.8...v1.1.10

v1.1.8

Choose a tag to compare

@rozx rozx released this 23 Oct 00:30
e9b1b0d

Release Notes v1.1.8 / 发布说明 v1.1.8

🎉 What's New / 新功能

Continuation Parts Relocation from Nested Containers / 从嵌套容器中重定位分卷续档

When an outer archive contains parts of a multipart set (e.g., a .zip holding MySet.7z.002), the tool now relocates those continuation parts next to their multipart set before attempting the multipart extraction. This guarantees the set is complete when extraction begins.

当外层档案包含多部分档案的续档(例如 .zip 内含 MySet.7z.002)时,工具会在尝试多部分提取前,将这些续档移动到对应的多部分集旁边,确保在开始提取时分卷齐全。

Highlights / 亮点:

  • Continuation parts found during nested extraction are no longer lost with temp cleanup—they are moved to the correct group (if possible).

  • Primary parts are still the only ones considered for recursive nested extraction.

  • A safety-net reconciliation pass scans the output folder to relocate any remaining parts before multipart extraction.

  • 在嵌套提取过程中发现的续档不再随临时清理丢失——若可能,将移动到正确的分组目录。

  • 递归嵌套提取仍仅针对主分卷执行。

  • 在多部分提取前,会对输出目录执行一次兜底扫描,将尚未移动到位的续档重定位。

🐛 Bug Fixes / 错误修复

Fix: Multipart extraction failing when a part was inside another container / 修复:当分卷在其他容器中时多部分提取失败

Issue / 问题: If one of the multipart volumes existed inside another archive, the tool didn’t place it next to the set before attempting extraction, causing missing-volume errors.

如果某个分卷存在于另一个档案内,工具在开始提取前没有将它放到多部分集旁边,导致缺失分卷错误。

Fix / 修复: Added a relocation callback to nested extraction that moves continuation parts into the correct multipart group directory immediately. Also added a reconciliation pass after single-archive extraction to relocate any parts that landed in the output folder.

在嵌套提取中新增重定位回调,立即将续档移动到对应的多部分组目录;并在单一档案提取结束后新增一次对输出目录的兜底扫描,重定位落在输出目录中的续档。

🔧 Improvements / 改进

  • Optional group_relocator callback in nested extraction to handle continuation parts discovered inside containers.

  • Output-folder reconciliation step ensures multipart sets are complete before extraction begins.

  • Clearer CLI messages (English/Chinese) showing when continuation parts are relocated.

  • 在嵌套提取中新增可选 group_relocator 回调,用于处理在容器中发现的续档。

  • 新增输出目录的兜底扫描步骤,确保开始多部分提取前分卷齐全。

  • 更清晰的 CLI 提示(中英文),在续档被移动时给出明确反馈。

📝 Documentation Updates / 文档更新

  • Updated AGENTS.md with the new nested multipart relocation behavior and the reconciliation pass.

  • Documented how continuation parts are identified and handled across formats (7z, RAR, ZIP, TAR.*).

  • 更新了 AGENTS.md,说明新增的嵌套续档重定位行为与兜底扫描步骤。

  • 文档化了不同格式(7z、RAR、ZIP、TAR.*)的续档识别与处理方式。

✅ Test Coverage / 测试覆盖

  • Added unit tests ensuring continuation parts found during nested extraction are relocated via the callback (or skipped) and do not leak into final_files.

  • Full test suite passes locally.

  • 新增单元测试,确保嵌套提取中发现的续档会通过回调被重定位(或被跳过),且不会泄漏到 final_files。

  • 本地完整测试套件全部通过。

⚙️ Technical Details / 技术细节

Modified Files / 修改的文件

  • complex_unzip_tool_v2/modules/archive_utils.py
    • Added optional group_relocator to extract_nested_archives() and used it when encountering continuation parts during nested scanning.
  • complex_unzip_tool_v2/main.py
    • Wired group_relocator to reuse file_utils.add_file_to_groups and added a reconciliation step after single-archive extraction.
  • complex_unzip_tool_v2/modules/file_utils.py
    • Added relocate_multipart_parts_from_directory(source_root, groups) to scan output folder and relocate parts into their group directories.
    • Kept strict base-name matching semantics to avoid cross-group misclassification.
  • tests/test_archive_utils.py
    • Added tests: continuation parts are relocated via callback and not included in final_files; skipped when not relocated.
  • AGENTS.md
    • Documented the new relocation and reconciliation behavior.

Validation / 验证

  • ✅ CLI verified on a sample real-world directory (e.g., E:\testDir - Copy).

  • ✅ 102 unit tests passing locally.

  • ✅ 在真实目录(例如 E:\\testDir - Copy)中验证。

  • ✅ 本地 102 个单元测试全部通过。

🚀 Migration Notes / 迁移说明

For Users / 用户须知

No breaking changes. The tool will more reliably extract multipart archives when some parts are inside containers.

无破坏性变化。当部分分卷位于容器内时,工具将更可靠地完成多部分提取。

For Developers / 开发者须知

  • extract_nested_archives() now accepts an optional group_relocator parameter. Existing calls continue to work (parameter is optional).

  • If you maintain custom extraction flows, consider wiring a relocator to ensure continuation parts found in nested contexts are handled immediately.

  • extract_nested_archives() 现已支持可选参数 group_relocator。现有调用无需修改(该参数是可选的)。

  • 若维护自定义提取流程,建议接入重定位逻辑,以便及时处理嵌套环境中发现的续档。


Full Changelog: v1.1.7...v1.1.8

完整变更日志: v1.1.7...v1.1.8