c++ FileCopyExW将最后一个错误报告为ERROR_NOT_SUPPORTED -这对于FileCopyExW意味着什么

sdnqo3pr  于 2023-02-10  发布在  其他
关注(0)|答案(1)|浏览(117)
    • 背景:**

我需要扫描,收集信息和复制一些媒体文件从特定的目录。
我一直有一些文件没有被检测到,等等相当麻烦

    • 问题:**
    • 读者警告:**如屏幕截图所示和评论中所述,该问题的标题和前提可能没有实际意义,因为错误更可能是dec 32(== 0x20)== ERROR_SHARING_VIOLATION,该问题的答案中有一个"简单"的解释。

在下面的代码中,我使用了一个c风格的转换来将我的QString转换为CopyFileExWLPCWSTR,这是我在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;
}
9w11ddsr

9w11ddsr1#

我建议您检查复制的文件句柄是否在另一个进程中打开。
我创建了一个简单的示例,代码如下:

#include <iostream>
#include <Windows.h>
using namespace std;

int main(int argc, const char* argv[])
{
    CopyFileEx(L"D:\\test\\test.txt", L"D:\\test\\test2.txt", NULL, NULL, 0, 0);
    int e = GetLastError();
    cout << "error code is :" << e << endl;
    return 0;
}

这个示例当然成功地复制了文件。但是如果我添加代码来打开这个文件的句柄,它将返回错误代码32。

#include <iostream>
#include <Windows.h>
using namespace std;

int main(int argc, const char* argv[])
{
    CreateFileW(L"D:\\test\\test.txt", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);
    CopyFileEx(L"D:\\test\\test.txt", L"D:\\test\\test2.txt", NULL, NULL, 0, 0);
    int e = GetLastError();
    cout << "error code is :" << e << endl;
    return 0;
}

输出:

所以我认为你在其他位置打开句柄后没有把它关闭好,如果你需要在句柄打开的时候复制文件,可以修改dwShareMode参数为FILE_SHARE_READ,这样就可以在句柄打开的时候进行文件复制操作。
以下是示例:

#include <iostream>
#include <Windows.h>
using namespace std;

int main(int argc, const char* argv[])
{
    CreateFileW(L"D:\\test\\test.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);
    CopyFileEx(L"D:\\test\\test.txt", L"D:\\test\\test2.txt", NULL, NULL, 0, 0);
    int e = GetLastError();
    cout << "error code is :" << e << endl;
    return 0;
}

输出:

更多参考:CreateFileWCopyFileExA

相关问题