Reputation: 169
I am working in Windows,using vc++2010 and MFC.
Following is my code:
CFile File;
TCHAR lpCause[1024];
CFileException eException;
CString strErrorMessage;
// a very long file path name means a file name over 255 characters
if (!File.Open(_T("a very long file path name"), CFile::modeCreate, &eException))
{
eException.GetErrorMessage(lpCause, 1024);
strErrorMessage = lpCause;
}
else
File.Close();
When I run the code, I got error message:"a very long file path name contains an incorrect path".
My questions are:
CreateFile()
function can add "\\\\?\"
in the beginning of file path, then it will extend this limit to 32767
wide characters.How can I do the same thing in MFC?Upvotes: 6
Views: 1429
Reputation: 27766
In the source of CFile::Open()
, there is an explicit check if the path length exceeds _MAX_PATH
:
if (lpszFileName != NULL && SUCCEEDED(StringCchLength(lpszFileName, _MAX_PATH, NULL)) )
If _MAX_PATH
is exceeded, the function sets pException->m_cause = CFileException::badPath
and returns FALSE
.
This is true even for the MFC version that comes with VS2017.
So the standard technique to circumvent the _MAX_PATH
limit, that is prefixing the path with \\?\
won't work.
Call CreateFileW()
directly to pass it a path with \\?\
prefix. Use the CFile
constructor that accepts a HANDLE
to manage the file through a CFile
object. The CFile
object will take ownership of the handle so you must not call CloseHandle()
on the handle.
HANDLE hFile = CreateFileW( L"\\\\?\\a very long file path name", GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, NULL );
if( hFile != INVALID_HANDLE_VALUE )
{
// Manage the handle using CFile
CFile file( hFile );
// Use the file...
// The CFile destructor closes the handle here.
}
else
{
DWORD err = GetLastError();
// TODO: do your error handling...
}
Another possibility is to derive a class from CFile
that overrides CFile::Open()
(which is virtual). For the implementation copy/paste the MFC source, but leave out the _MAX_PATH
check. For a big project, this class could be a drop-in replacement for CFile
to enable long paths. You could even go so far to prepend the \\?\
prefix if it isn't already there (but that is more involved as the prefix also disables the regular transformations from a Win32 path to a NT-style path, like converting /
to \
, resolving dots and so on).
Upvotes: 7