zet*_*zet 6 c++ windows winapi mfc
我在Windows中工作,使用vc ++ 2010和MFC.
以下是我的代码:
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();
Run Code Online (Sandbox Code Playgroud)
当我运行代码时,我收到错误消息:"一个很长的文件路径名包含一个不正确的路径".
我的问题是:
CreateFile()函数可以"\\\\?\"在文件路径的开头添加,然后它会将此限制扩展为32767宽字符.如何在MFC中执行相同的操作?在源代码中CFile::Open(),有一个明确的检查路径长度是否超过_MAX_PATH:
if (lpszFileName != NULL && SUCCEEDED(StringCchLength(lpszFileName, _MAX_PATH, NULL)) )
Run Code Online (Sandbox Code Playgroud)
如果_MAX_PATH超过,则函数设置pException->m_cause = CFileException::badPath并返回FALSE.
即使对于VS2017附带的MFC版本也是如此.
因此,规避_MAX_PATH限制的标准技术(即为路径添加前缀)\\?\将不起作用.
CreateFileW()直接调用以传递带\\?\前缀的路径.使用CFile接受a 的构造函数HANDLE通过CFile对象管理文件.该CFile对象将获得句柄的所有权,因此您不能调用CloseHandle()句柄.
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...
}
Run Code Online (Sandbox Code Playgroud)
另一种可能性是从CFile该覆盖CFile::Open()(虚拟)派生类.对于实现复制/粘贴MFC源,但不做_MAX_PATH检查.对于一个大项目,这个类可以作为CFile启用长路径的替代品.如果\\?\前缀不存在,你甚至可以将前缀添加到前面(但由于前缀还禁用从Win32路径到NT风格路径的常规转换,如转换/为\,解析点等等,因此更加复杂.上).