In addition to configuring windows for long path support you must also have your application opt-in to the feature by providing a manifest that does so. See the documentation at Maximum Path Length Limitation
How to write C programs that can use long > 260 pathnames?
Hi,
I have enabled Long Paths in the Group Policy Editor, rebooted, and tested this code:
LPCWSTR fileEXT;
fileEXT = L"D:\m1\pro\long\12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________.txt";
//fileEXT = L"D:\m1\pro\long\12________12_";
HANDLE hnd = CreateFileW(fileEXT, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hnd == INVALID_HANDLE_VALUE)
That works with the short name commented out here, but not with the long one.
What am I doing wrong?
Note: that also fails using CreateFileW()
C++
-
Viorel 118K Reputation points
2024-08-19T11:56:54.4633333+00:00 Maybe the space after “.txt” should be removed. Although, it should work in both cases.
-
RLWA32 45,701 Reputation points
2024-08-19T12:35:33.5733333+00:00 @Robert Benaroya, The \\?\ prefix for exceeding maximum path length limitations predates the long path support introduced in Win 10. It is a completely different feature provided by the operating system.
-
Minxin Yu 12,086 Reputation points • Microsoft Vendor
2024-08-19T13:14:25.4733333+00:00 From the answer provided by RLWA32,
To enable the new long path behavior per application, two conditions must be met. A registry value must be set, and the application manifest must include the
longPathAware
element.And try without \?\ prefix.
If the answer is the right solution, please click "Accept Answer" and kindly upvote it.
Sign in to comment
-
RLWA32 45,701 Reputation points
2024-08-19T11:46:51.1133333+00:00 -
RLWA32 45,701 Reputation points
2024-08-19T15:13:44.3833333+00:00 When it is built with the necessary manifest the following sample successfully created a very deep directory structure (exceeding MAX_PATH) and then successfully created a file on a Win10 22H2 system that supports long paths. The sample can be built for unicode (utf-16le) or non-unicode.
Sample code --
#define WIN32_LEAN_AND_MEAN #include <Windows.h> #include <stdlib.h> #include <stdio.h> #include <tchar.h> int main() { LPCTSTR aComponents[] = { _T("\\VeryLongPathNameComponentForLongPathAwareTesting1"), _T("\\VeryLongPathNameComponentForLongPathAwareTesting2"), _T("\\VeryLongPathNameComponentForLongPathAwareTesting3"), _T("\\VeryLongPathNameComponentForLongPathAwareTesting4"), _T("\\VeryLongPathNameComponentForLongPathAwareTesting5"), }; TCHAR szPath[300] = _T("C:\\Users\\RLWA32\\Documents"); for (int i = 0; i < ARRAYSIZE(aComponents); i++) { _tcscat_s(szPath, ARRAYSIZE(szPath), aComponents[i]); if (!CreateDirectory(szPath, NULL)) { _tprintf_s(_T("CreateDirectory failed with error %d for %s\n"), GetLastError(), aComponents[i]); exit(3); } } TCHAR szName[] = _T("\\TestFile.txt"); _tcscat_s(szPath, ARRAYSIZE(szPath), szName); _tprintf_s(_T("Length of path is %llu characters\n"), (ULONGLONG) _tcslen(szPath)); HANDLE hFile = CreateFile(szPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { _tprintf_s(_T("CreateFile Succeeded!!")); CloseHandle(hFile); } else _tprintf_s(_T("CreateFile failed with error %d\n"), GetLastError()); return 0; }
The manifest that was used -
<?xml version="1.0" encoding="utf-8"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> <asmv3:application> <asmv3:windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings"> <ws2:longPathAware>true</ws2:longPathAware> </asmv3:windowsSettings> </asmv3:application> </assembly>
And the result of the test
-
Robert Benaroya 20 Reputation points
2024-08-19T15:26:42.4033333+00:00 It's nice to know that I don't need the ?\ prefix, it was ChatGPT that told me it was necessary!
About the manifest, I'm not very familiar with VS gui, how do you do it? I tried to follow what's on this page, but did not succeed.
The main app that needs to support long path is an app written with command line tools, being ported a long long time ago from a Sun workstation.
I use cl and link directly within a makefile. It must stay this way, that allows to propagate changes easily between Unix and Windows. I use VS mainly for debugging.
Or in the case described above, just to test the feature in an environment that is standard. Once it will work within VS, I'll try to make it work from the command line.
How do I embed a manifest with command line arguments?
-
RLWA32 45,701 Reputation points
2024-08-19T16:18:54.41+00:00 Visual Studio will do all the heavy lifting for you when it comes to embedding manifests in an executable. For the sample that I posted above I added a text file to the VS2022 project. I renamed it so that it had a .manifest extension and inserted the necessary manifest xml into it.
A seen in the project's solution explorer pane -
Then open the property page for the manifest file (e.g., LongPath.manifest in the sample) and make sure that its properties look like this -
Visual Studio handles the rest when it builds the application.
Embedding manifests into applications built with command line tools is a different subject. I suggest you ask a new question about it. You can get started by referring to https://learn.microsoft.com/en-us/cpp/build/understanding-manifest-generation-for-c-cpp-programs?view=msvc-170
-
Robert Benaroya 20 Reputation points
2024-08-19T16:50:32.28+00:00 Thanks for the very detailed answer with screen caps, I really appreciate it.
Please bear with me, I know well C, but I just scratched the surface with C++, all my projects predate ANSI C!
My code is:
#include <iostream> #include <Windows.h> #include <tchar.h> int main() { // LPCSTR fileEXT; LPCWSTR fileEXT; fileEXT = L"D:\\m1\\pro\\long\\12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________.txt"; //fileEXT = L"D:\\m1\\pro\\long\\12________12_"; HANDLE hnd = CreateFileW(fileEXT, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (hnd == INVALID_HANDLE_VALUE) { _tprintf_s(_T("CreateFile failed with error %d\n"), GetLastError()); } } }
It's a copy of my main app C code.
I followed your instruction building the manifest file and verifying that it looks like your screen cap, and I still get an error 123.
To add insult to injury, when trying again, I get at build:
1>LINK : fatal error LNK1327: failure during running mt.exe
-
Robert Benaroya 20 Reputation points
2024-08-19T18:10:04.1333333+00:00 I recreated this simple project from scratch, which eliminated the LNK1337 error, no idea how it happened.
I'm still getting the 123 error.
-
Robert Benaroya 20 Reputation points
2024-08-19T18:43:37.4466667+00:00 Hi,
When using your code exactly, it works.
But when I don't create many sublevels as you did, but only one very long filename with:
C int main() { LPCTSTR aComponents[] = { _T("\\long"), }; TCHAR szPath[3000] = _T("d:\\m1\\pro"); for (int i = 0; i < ARRAYSIZE(aComponents); i++) { _tcscat_s(szPath, ARRAYSIZE(szPath), aComponents[i]); // if (!CreateDirectory(szPath, NULL)) // { // _tprintf_s(_T("CreateDirectory failed with error %d for %s\n"), GetLastError(), aComponents[i]); // exit(3); // } } TCHAR szName[] = _T("\\12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________12________.txt"); _tcscat_s(szPath, ARRAYSIZE(szPath), szName); _tprintf_s(_T("Length of path is %llu characters\n"), (ULONGLONG)_tcslen(szPath)); HANDLE hFile = CreateFile(szPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { _tprintf_s(_T("CreateFile Succeeded!!")); CloseHandle(hFile); } else _tprintf_s(_T("CreateFile failed with error %d\n"), GetLastError()); return 0; }
I get:
Length of path is 319 characters CreateFile failed with error 123
same as with my original program.
Since yours worked, the manifest is correct. Apparently, there is a restriction for the name length of a file itself, even if the total length is below 32767.
Am I correct?
-
Viorel 118K Reputation points
2024-08-19T18:47:43.1033333+00:00 Probably such long filenames cannot be enabled.
-
RLWA32 45,701 Reputation points
2024-08-19T18:49:37.7966667+00:00 If you read the documentation about Maximum path lengths again you will see guidance that says "This type of path is composed of components separated by backslashes, each up to the value returned in the lpMaximumComponentLength parameter of the GetVolumeInformation function (this value is commonly 255 characters)." In other words, the length of any part of a fully qualified path between the backslashes has a limit. While the entire path can be very long, no component can exceed that limit.
-
Deleted
This comment has been deleted due to a violation of our Code of Conduct. The comment was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.
-
RLWA32 45,701 Reputation points
2024-08-20T08:35:40.7666667+00:00 @Robert Benaroya, It appears that the Q&A site has deleted the last comment you posted. These stealth deletions are an ongoing problem with this site. You may want to keep an eye on your future posts to ensure that they are not also deleted.
-
Robert 0 Reputation points
2024-08-20T11:10:58.3933333+00:00 I was just thanking you, you solved my problem.
-
RLWA32 45,701 Reputation points
2024-08-20T12:40:35.3533333+00:00 You're welcome. By the way, if you use your command line tools to build 32-bit applications without manifests you could be inadvertently subjecting them to UAC file and registry virtualization.
Sign in to comment -