mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-19 13:41:03 +00:00
fix: max filepath length on windows (#16552)
# Description <!-- > Please provide a summary of the changes made in this PR. Include details such as: > * What issue does this PR address or fix? > * What new features or enhancements does this PR introduce? > * Are there any breaking changes or dependencies that need to be considered? --> Windows traditionally limits many file operations to `MAX_PATH` (260 characters). Deeply nested plugin packages can exceed this limit during `.whl` extraction, leaving files missing and causing the plugin to fail to load. This change adds a shared extended_path helper that prepares paths for Windows file operations using the extended-length prefixes `\\?\` or `\\?\UNC\`. The helper is used for ZIP archive I/O and extraction destinations, including plugin wheel extraction. This avoids relying on the Windows long-path setting, which changes machine-wide settings. Paths remain unprefixed outside file operations. Code that bypasses the shared ZIP helpers may still require separate long-path handling. See [Microsoft's documentation on path length limitation](https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry) # Screenshots/Recordings/Graphs <!-- > Please attach relevant screenshots to showcase the UI changes. > Please attach images that can help explain the changes. --> ## Tests <!-- > Please describe the tests that you have conducted to verify the changes made in this PR. --> Tested on Windows 11 by using a portable installation of OrcaSlicer and placing it in some really long filepath length e.g. `C:/somename/<240 characters long folder path>/OrcaSlicer` and then running and trying to install any plugin locally or on OrcaCloud. <!-- > A guide for users on how to download the artifacts from this PR. --> [How to Download Pull Requests Artifacts for Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)
This commit is contained in:
1 parent
caade80624
commit
cefdd9b609
8 files changed
+276
-25
No files matched your search
@@ -2254,5 +2254,45 @@ bool check_layer_id_pattern(const std::string& pattern, int layer_id){
|
||||
return mod >= 0 && mod < count;
|
||||
}
|
||||
|
||||
boost::filesystem::path extended_path(const boost::filesystem::path& path) {
|
||||
#ifdef WIN32
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
// Already extended, or an explicit device path (which is not subject to MAX_PATH and must not
|
||||
// be absolutized or normalized): leave it alone.
|
||||
{
|
||||
fs::path prefix_candidate = path;
|
||||
const std::wstring native = prefix_candidate.make_preferred().wstring();
|
||||
if (native.rfind(L"\\\\?\\", 0) == 0 || native.rfind(L"\\\\.\\", 0) == 0)
|
||||
return fs::path(native);
|
||||
}
|
||||
|
||||
fs::path absolute = path;
|
||||
if (!absolute.is_absolute()) {
|
||||
boost::system::error_code ec;
|
||||
absolute = fs::absolute(absolute, ec);
|
||||
if (ec)
|
||||
return path; // can't form a valid prefixed path from a relative one
|
||||
}
|
||||
|
||||
// A trailing separator is redundant to the Win32 APIs, but lexically_normal() would rewrite it
|
||||
// as a "." element, which the "\\?\" prefix (normalisation off) takes literally. Drop it first.
|
||||
while (absolute.has_relative_path() && absolute.filename() == ".")
|
||||
absolute = absolute.parent_path();
|
||||
|
||||
// The "\\?\" prefix turns off Win32 normalisation, so do it here first.
|
||||
absolute = absolute.lexically_normal();
|
||||
|
||||
// Extended paths only recognize backslash separators.
|
||||
const std::wstring native = absolute.make_preferred().wstring();
|
||||
if (native.empty())
|
||||
return path;
|
||||
if (native.rfind(L"\\\\", 0) == 0)
|
||||
return fs::path(L"\\\\?\\UNC\\" + native.substr(2)); // \\server\share\... -> \\?\UNC\server\share\...
|
||||
return fs::path(L"\\\\?\\" + native); // C:\dir\... -> \\?\C:\dir\...
|
||||
#else
|
||||
return path;
|
||||
#endif
|
||||
}
|
||||
|
||||
}; // namespace Slic3r
|
||||
Reference in new issue
Block a user