Fix extraction failure on long paths (>260 chars) with \?\ prefix
Build and Release / build (push) Has been cancelled
Build and Release / build (push) Has been cancelled
Add longPathForWindows() helper that prefixes extract target directories with \?\ on Windows, bypassing the 260-char MAX_PATH limit. Applied to both WinRAR/UnRAR and 7z arguments. Fixes "Die Syntax für den Dateinamen, Verzeichnisnamen" errors when archive internal directories create deeply nested output paths. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
a22a90adf3
commit
2ae22f942e
+18
-2
@@ -8,6 +8,21 @@ import { logger } from "./logger";
|
||||
import { removeDownloadLinkArtifacts, removeSampleArtifacts } from "./cleanup";
|
||||
|
||||
const DEFAULT_ARCHIVE_PASSWORDS = ["", "serienfans.org", "serienjunkies.org"];
|
||||
|
||||
/**
|
||||
* On Windows, prefix an absolute path with \\?\ to bypass the 260-char MAX_PATH limit.
|
||||
* WinRAR 5.x+ and 7-Zip support this prefix for long output paths.
|
||||
*/
|
||||
function longPathForWindows(p: string): string {
|
||||
if (process.platform !== "win32") return p;
|
||||
const resolved = path.resolve(p);
|
||||
if (resolved.startsWith("\\\\?\\")) return resolved;
|
||||
if (resolved.startsWith("\\\\")) {
|
||||
// UNC path \\server\share -> \\?\UNC\server\share
|
||||
return "\\\\?\\UNC\\" + resolved.slice(2);
|
||||
}
|
||||
return "\\\\?\\" + resolved;
|
||||
}
|
||||
const NO_EXTRACTOR_MESSAGE = "WinRAR/UnRAR nicht gefunden. Bitte WinRAR installieren.";
|
||||
|
||||
let resolvedExtractorCommand: string | null = null;
|
||||
@@ -606,13 +621,14 @@ export function buildExternalExtractArgs(
|
||||
const perfArgs = usePerformanceFlags && shouldUseExtractorPerformanceFlags()
|
||||
? ["-idc", extractorThreadSwitch()]
|
||||
: [];
|
||||
return ["x", overwrite, pass, "-y", ...perfArgs, archivePath, `${targetDir}${path.sep}`];
|
||||
const longTarget = longPathForWindows(targetDir);
|
||||
return ["x", overwrite, pass, "-y", ...perfArgs, archivePath, `${longTarget}${path.sep}`];
|
||||
}
|
||||
|
||||
const overwrite = mode === "overwrite" ? "-aoa" : mode === "rename" ? "-aou" : "-aos";
|
||||
// NOTE: Same password-in-args limitation as above applies to 7z as well.
|
||||
const pass = password ? `-p${password}` : "-p";
|
||||
return ["x", "-y", overwrite, pass, archivePath, `-o${targetDir}`];
|
||||
return ["x", "-y", overwrite, pass, archivePath, `-o${longPathForWindows(targetDir)}`];
|
||||
}
|
||||
|
||||
async function resolveExtractorCommandInternal(): Promise<string> {
|
||||
|
||||
Reference in New Issue
Block a user