- 背景:**
我需要扫描,收集信息和复制一些媒体文件从特定的目录。
我一直有一些文件没有被检测到,等等相当麻烦
- 问题:**
- 读者警告:**如屏幕截图所示和评论中所述,该问题的标题和前提可能没有实际意义,因为错误更可能是dec 32(== 0x20)== ERROR_SHARING_VIOLATION,该问题的答案中有一个"简单"的解释。
在下面的代码中,我使用了一个c风格的转换来将我的QString
转换为CopyFileExW
的LPCWSTR
,这是我在this SO post中找到的。我尝试了许多不同的转换,但似乎没有一个能正确工作 *-这是目前的重点之外 *。
这种"转换"技术带来的问题是错误ERROR_NOT_SUPPORTED
错误_不支持
50(0x32)
不支持该请求。
坦率地说,在这种情况下,这对我来说绝对没有意义。我正在从NTFS-〉NTFS(用于测试的同一硬盘驱动器)复制,目标文件长度〈200个字符(见图片,确切地说是192个字符)。
- 核心代码:(详情请参见底部)**
// QString src (src file location), dst (destination file location)
LPCWSTR localC_src = (LPCWSTR) src.utf16();
LPCWSTR localC_dst = (LPCWSTR) dst.utf16();
LPCWSTR dirC = (LPCWSTR) dir.utf16();
auto rc = CopyFileExW(localC_src, localC_dst, &BackupManager::copyProgress, this, &bStopBackup, 0);
if (rc == 0) {
DWORD lastError = GetLastError(); // Error = 0x32
bool dirExist = DirExists(dirC); // true
bool fileExists = FileExists(localC_src); // true
printWarning(TAG, QString("File Copy Error: %1").arg(getLastErrorMsg()));
#ifdef QT_DEBUG
if (FileExists(localC_src)) {
qDebug() << "#FailedCopy: Windows file exists but copy failed" << src; // this gets hit using the implemented c-style cast
}
else {
if (QFile::exists(src)) {
qDebug() << "#FailedCopy: Windows is really being full of shit! " << src; // this always gets triggered when using QString::toStdWString.c_str()
}
else {
qDebug() << "#FailedCopy: Windows file copy failed outright" << src;
}
}
// ...
} else {
// success
}
在FileCopyExW
上下文中,此错误意味着什么?
(另外,如果有人有windows. h实现的源代码,可以让我进一步跟踪错误,请将其作为评论发布)*
- 调试器等的图像**
- 调试器等的图像**
- 完整代码实现:**
static QString toString(HRESULT hr)
{
_com_error err{hr};
const TCHAR* lastError = err.ErrorMessage();
return QStringLiteral("Error 0x%1: %2").arg((quint32)hr, 8, 16, QLatin1Char('0'))
.arg(lastError);
}
static QString getLastErrorMsg()
{
DWORD lastError = GetLastError();
QString s = toString(HRESULT_FROM_WIN32(lastError));
return s;
}
BOOL FileExists(LPCWSTR szPath)
{
DWORD dwAttrib = GetFileAttributes(szPath);
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
// not used
static const wchar_t* toLPCWSTR(QString s)
{
std::wstring dstWString = s.toStdWString();
const wchar_t* localC_src = dstWString.c_str();
return localC_src;
}
static bool DirExists(LPCWSTR szPath)
{
DWORD ftyp = GetFileAttributes(szPath);
if (ftyp == INVALID_FILE_ATTRIBUTES)
return false; //something is wrong with your path!
if (ftyp & FILE_ATTRIBUTE_DIRECTORY)
return true; // this is a directory!
return false; // this is not a directory!
}
BackupResult BackupManager::copyFile(QString m_src, QString m_dst)
{
QFileInfo fi(m_src);
QString dir = fi.dir().path();
// const wchar_t* dirC = toLPCWSTR(dir);
QString src = QString(m_src).replace("/", "\\");
QString dst = QString(m_src).replace("/", "\\");
// const wchar_t* localC_src = toLPCWSTR(src);
// const wchar_t* localC_dst = toLPCWSTR(dst);
LPCWSTR localC_src = (LPCWSTR) src.utf16();
LPCWSTR localC_dst = (LPCWSTR) dst.utf16();
LPCWSTR dirC = (LPCWSTR) dir.utf16();
auto rc = CopyFileExW(localC_src, localC_dst, &BackupManager::copyProgress, this, &bStopBackup, 0);
if (rc == 0) {
DWORD lastError = GetLastError(); // Error = 0x32
bool dirExist = DirExists(dirC); // true
bool fileExists = FileExists(localC_src); // true
printWarning(TAG, QString("File Copy Error: %1").arg(getLastErrorMsg()));
#ifdef QT_DEBUG
if (FileExists(localC_src)) {
qDebug() << "#FailedCopy: Windows file exists but copy failed" << src; // this gets hit using the implemented c-style cast
}
else {
if (QFile::exists(src)) {
qDebug() << "#FailedCopy: Windows is really being full of shit! " << src; // this always gets triggered when using QString::toStdWString.c_str()
}
else {
qDebug() << "#FailedCopy: Windows file copy failed outright" << src;
}
}
#endif
// copy failed
return BackupResult::IOError;
}
// copy success
return BackupResult::Success;
}
1条答案
按热度按时间9w11ddsr1#
我建议您检查复制的文件句柄是否在另一个进程中打开。
我创建了一个简单的示例,代码如下:
这个示例当然成功地复制了文件。但是如果我添加代码来打开这个文件的句柄,它将返回错误代码32。
输出:
所以我认为你在其他位置打开句柄后没有把它关闭好,如果你需要在句柄打开的时候复制文件,可以修改
dwShareMode
参数为FILE_SHARE_READ
,这样就可以在句柄打开的时候进行文件复制操作。以下是示例:
输出:
更多参考:
CreateFileW
和CopyFileExA