Windows Win32 MoveFile在重命名包含子文件夹的文件夹时返回错误\u访问\u拒绝 我的C++应用程序使用了重命名文件夹,但是在给定条件下,它返回 ErrRoAccess禁止/。条件如下: 文件夹必须至少包含一个子文件夹 子文件夹必须在尝试重命名之前已打开

Windows Win32 MoveFile在重命名包含子文件夹的文件夹时返回错误\u访问\u拒绝 我的C++应用程序使用了重命名文件夹,但是在给定条件下,它返回 ErrRoAccess禁止/。条件如下: 文件夹必须至少包含一个子文件夹 子文件夹必须在尝试重命名之前已打开,windows,winapi,Windows,Winapi,Win32 MoveFile在重命名包含子文件夹的文件夹时返回错误\u访问\u拒绝 我的C++应用程序使用了重命名文件夹,但是在给定条件下,它返回 ErrRoAccess禁止/。条件如下: 文件夹必须至少包含一个子文件夹 子文件夹必须在尝试重命名之前已打开 Windows资源管理器文件管理器文件夹选项“展开以打开文件夹”已选中 其他意见 告诉用户取消选中“展开以打开文件夹”选项是不可能的 如果在WINDOWS资源管理器上手动重命名文件夹,则不会出现此错误 该文件夹可能有国际字符,因此,根据,我

Win32 MoveFile在重命名包含子文件夹的文件夹时返回错误\u访问\u拒绝

我的C++应用程序使用了重命名文件夹,但是在给定条件下,它返回<代码> ErrRoAccess禁止/<代码>。条件如下:

  • 文件夹必须至少包含一个子文件夹
  • 子文件夹必须在尝试重命名之前已打开
  • Windows资源管理器文件管理器文件夹选项“展开以打开文件夹”已选中
  • 其他意见
    • 告诉用户取消选中“展开以打开文件夹”选项是不可能的
    • 如果在WINDOWS资源管理器上手动重命名文件夹,则不会出现此错误
    • 该文件夹可能有国际字符,因此,根据,我不应该使用
    一些问题
    • 为什么我会犯这个错误
    • 是否有更佳的C++函数或改名文件夹的解决办法?
    • 为什么手动重命名文件夹不会输出此错误?Windows资源管理器使用什么功能
    最小、完整和可验证的示例
    拒绝访问错误(5)表示“子文件夹”已打开,或者此树中的某个文件已打开。如果“文件夹”本身的句柄在没有删除访问共享的情况下被打开,那么这将是一个共享冲突错误(32)。请参阅:“如果目录或其任何子目录包含具有打开句柄的文件,则无法重命名该目录”。资源管理器无法。打开CMD并执行
    cd/d:\folder\subfolder
    。现在尝试在资源管理器中重命名“D:\folder”。它将失败。shell可能足够聪明,可以释放句柄以允许重命名继续。请改为尝试
    SHFileOperation
    。@yellow01,但如果除资源管理器之外的任何内容对树中的任何文件打开了句柄,或者将任何子目录作为其工作目录打开,则它仍然不起作用。用户只需知道这种行为,并关闭阻止操作成功的程序或外壳;这是“导航窗格:展开以打开文件夹”。使用Process Explorer查看Explorer.exe中的句柄。在导航窗格中展开目录时,即使是手动展开,也会打开目录的一个或多个句柄,这些句柄保持打开状态(可能是为了监视目录更改),直到资源管理器窗口关闭。拒绝访问错误(5)表示“子文件夹”已打开,或者此树中的某个文件已打开。如果“文件夹”本身的句柄在没有删除访问共享的情况下被打开,那么这将是一个共享冲突错误(32)。请参阅:“如果目录或其任何子目录包含具有打开句柄的文件,则无法重命名该目录”。资源管理器无法。打开CMD并执行
    cd/d:\folder\subfolder
    。现在尝试在资源管理器中重命名“D:\folder”。它将失败。shell可能足够聪明,可以释放句柄以允许重命名继续。请改为尝试
    SHFileOperation
    。@yellow01,但如果除资源管理器之外的任何内容对树中的任何文件打开了句柄,或者将任何子目录作为其工作目录打开,则它仍然不起作用。用户只需知道这种行为,并关闭阻止操作成功的程序或外壳;这是“导航窗格:展开以打开文件夹”。使用Process Explorer查看Explorer.exe中的句柄。在导航窗格中展开目录时,即使是手动展开,也会打开一个或多个保持打开状态的目录句柄(可能是为了观察目录更改),直到资源管理器窗口关闭。
    #include <windows.h>
    #include <strsafe.h>
    
    void ErrorExit(LPTSTR lpszFunction)
    {
        // Retrieve the system error message for the last-error code
    
        LPVOID lpMsgBuf;
        LPVOID lpDisplayBuf;
        DWORD dw = GetLastError();
    
        FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER |
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            dw,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPTSTR)&lpMsgBuf,
            0, NULL);
    
        // Display the error message and exit the process
    
        lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
            (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
        StringCchPrintf((LPTSTR)lpDisplayBuf,
            LocalSize(lpDisplayBuf) / sizeof(TCHAR),
            TEXT("%s failed with error %d: %s"),
            lpszFunction, dw, lpMsgBuf);
        MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
    
        LocalFree(lpMsgBuf);
        LocalFree(lpDisplayBuf);
        ExitProcess(dw);
    }
    
    void main()
    {
        // Generate an error
    
        if (!MoveFile("D:\\folder", "D:\\new_folder"))
            ErrorExit(TEXT("GetProcessId"));
    }
    
    D:
    └───folder
        └───subfolder