【问题标题】:RemoveDirectory() function in win32 api doesn't remove parent directory after removing subdirectories [duplicate]win32 api中的RemoveDirectory()函数在删除子目录后不会删除父目录[重复]
【发布时间】:2014-02-18 20:54:16
【问题描述】:

在删除子文件夹/文件后删除目录时遇到问题。我正在使用 FindFirstFile、FindNextFile、RemoveDirectory 等。例如我有这个目录:

C:\Users\user\Desktop\SearchFile\ipch\searchfile-e3798fd4\some-files-here.ipch

我的程序运行后,就剩下这个了

C:\Users\user\Desktop\SearchFile\ipch

如您所见,它删除了 searchfile-e3798fd4 中的所有文件并删除了该目录,但保留了父目录“ipch”,我也想将其删除。这是我当前的完整代码:

#include <Windows.h>
#include <wchar.h>
#include <stdio.h>

bool DeleteDirectory( const wchar_t *sDir )
{
    WIN32_FIND_DATA fdFile;
    HANDLE hFind;
    wchar_t sPath[ MAX_PATH * 10 ];

    wsprintf( sPath, L"%s\\*.*", sDir );

    if( ( hFind = FindFirstFile( sPath, &fdFile ) ) == INVALID_HANDLE_VALUE )
    {
        return false;
    }

    do
    {
        if( wcscmp( fdFile.cFileName, L"." ) != 0 &&
            wcscmp( fdFile.cFileName, L".." ) != 0 )
        {
            wsprintf( sPath, L"%s\\%s", sDir, fdFile.cFileName );

            if( fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
            {
                // Is Directory
                RemoveDirectory( sPath );
                DeleteDirectory( sPath );
            }
        }
    } while( FindNextFile( hFind, &fdFile ) );

    FindClose( hFind );
    return true;
}
bool DeleteFiles( const wchar_t *sDir, WIN32_FIND_DATA fdFile, HANDLE hFind )
{
    wchar_t sPath[ MAX_PATH * 10 ];

    wsprintf( sPath, L"%s\\*.*", sDir );

    if( ( hFind = FindFirstFile( sPath, &fdFile ) ) == INVALID_HANDLE_VALUE )
    {
        MessageBox( NULL, L"123", L"123", MB_OK );
        return false;
    }

    do
    {
        if( wcscmp( fdFile.cFileName, L"." ) != 0 &&
            wcscmp( fdFile.cFileName, L".." ) != 0 )
        {
            wsprintf( sPath, L"%s\\%s", sDir, fdFile.cFileName );

            if( fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
            {
                // Is Directory
                DeleteFiles( sPath, fdFile, hFind );
            }
            else
            {
                // Is File
                DeleteFile( sPath );
            }
        }
    } while( FindNextFile( hFind, &fdFile ) );


    FindClose( hFind );
    return true;
}
bool DeleteFolderContents( const wchar_t *sDir )
{
    WIN32_FIND_DATA fdFile;
    HANDLE hFind = NULL;
    wchar_t sPath[ MAX_PATH * 10 ];

    wsprintf( sPath, L"%s\\*.*", sDir );

    if( ( hFind = FindFirstFile( sPath, &fdFile ) ) == INVALID_HANDLE_VALUE )
    {
        MessageBox( NULL, L"", L"", MB_OK );
        return false;
    }

    do
    {
        if( wcscmp( fdFile.cFileName, L"." ) != 0 &&
            wcscmp( fdFile.cFileName, L".." ) != 0 )
        {
            wsprintf( sPath, L"%s\\%s", sDir, fdFile.cFileName );

            if( fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
            {
                // Is Directory
                if( wcscmp( fdFile.cFileName, L"Debug" ) == 0 ||
                    wcscmp( fdFile.cFileName, L"Release" ) == 0 ||
                    wcscmp( fdFile.cFileName, L"ipch" ) == 0 )
                {
                    DeleteFiles( sPath, fdFile, hFind );
                }
                DeleteFolderContents( sPath );
            }
        }
    } while( FindNextFile( hFind, &fdFile ) );

    FindClose( hFind );
    return true;
}
bool ListDirectoryContents( const wchar_t *sDir )
{
    WIN32_FIND_DATA fdFile;
    HANDLE hFind = NULL;
    wchar_t sPath[ MAX_PATH * 10 ];

    wsprintf( sPath, L"%s\\*.*", sDir );

    if( ( hFind = FindFirstFile( sPath, &fdFile ) ) == INVALID_HANDLE_VALUE )
    {
        MessageBox( NULL, L"Path not found", L"Error", MB_OK | MB_ICONERROR );
        return false;
    }

    do
    {
        if( wcscmp( fdFile.cFileName, L"." ) != 0 &&
            wcscmp( fdFile.cFileName, L".." ) != 0 )
        {
            wsprintf( sPath, L"%s\\%s", sDir, fdFile.cFileName );

            if( fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
            {
                // Is Directory
                if( wcscmp( fdFile.cFileName, L"Debug" ) == 0 ||
                    wcscmp( fdFile.cFileName, L"Release" ) == 0 ||
                    wcscmp( fdFile.cFileName, L"ipch" ) == 0 )
                {
                    // Working in debug folder
                    wprintf( L"[+] %s\n", sPath );
                }
                ListDirectoryContents( sPath );
            }
            else
            {
                // Is File
                wprintf( L"[-] %s\n", sPath );
            }
        }
    } while( FindNextFile( hFind, &fdFile ) );

    FindClose( hFind );
    return true;
}
int main()
{
    wchar_t pathName[] = L"C:\\Users\\user\\Desktop\\SearcFile\\";

    // List Directory Contents
    ListDirectoryContents( pathName );
    wprintf( L"\n" );
    system("pause");

    // Delete Folder Contents
    DeleteFolderContents( pathName );
    DeleteDirectory( pathName );
    wprintf( L"\n" );
    system("pause");

    ListDirectoryContents( pathName );
    wprintf( L"\n" );
    system("pause");

    return 0;
}

我知道问题存在于我实际 RemoveDirectory(sPath);因为调用了该函数,所以它看到 ipch 不为空,因此不会删除它。然后递归并继续。

【问题讨论】:

    标签: c++ winapi directory parent


    【解决方案1】:

    您的递归存在三个问题,使其与 Tim 描述的算法不匹配:

    1. 您正试图删除内容之前的目录。但RemoveDirectory 只删除空目录。
    2. 您(尝试)删除子目录,但保留文件。这也将阻止删除目录。
    3. 您永远不会删除原始目录。

    RemoveDirectory调用从循环内部移动到函数末尾将解决这些问题。

    【讨论】:

      【解决方案2】:

      我没有看你所有的代码,但我想,就像@BenVoigt 和@TimBergel 所说,你需要这样的东西:

      } while( FindNextFile( hFind, &fdFile ) );
      
      ::RemoveDirectory (sDir) ; // Add this here.
      
      FindClose( hFind );
      return true;
      

      这是一个完整的示例,只是为了给你一个想法:

      #include <string>
      
      #include <Windows.h>
      
      #define DIR L"C:\\Users\\user\\Desktop\\SearchFile\\ipch"
      
      BOOL RmDir (const std::wstring &strDir) ;
      BOOL IsDots (const std::wstring &strName) ;
      BOOL IsDir (const WIN32_FIND_DATA &fdFile) ;
      
      int main (void)
      {
          if (RmDir (DIR) == FALSE) {
              return 1 ;
          }
      
          return 0 ;
      }
      
      BOOL RmDir (const std::wstring &strDir)
      {
          WIN32_FIND_DATA fdFile ;
          ::memset (&fdFile, 0, sizeof (fdFile)) ;
      
          HANDLE hFind = INVALID_HANDLE_VALUE ;
      
          std::wstring strSearch = strDir + L"\\*.*" ;
      
          hFind = ::FindFirstFile (strSearch.data (), &fdFile) ;
      
          if (hFind == INVALID_HANDLE_VALUE) {
              return FALSE ;
          }
      
          do {    
              std::wstring strDelete = strDir + L"\\" + fdFile.cFileName ;
      
              if (IsDir (fdFile) == TRUE) {
                  if (IsDots (fdFile.cFileName) == TRUE) {
                      continue ;
                  }
      
                  RmDir (strDelete) ;
              }
      
              else {
      
                  ::DeleteFile (strDelete.data ()) ;
              }
      
          } while (::FindNextFile (hFind, &fdFile) == TRUE) ;
      
          ::FindClose (hFind) ;
          ::RemoveDirectory (strDir.data ()) ;
      
          return TRUE ;
      }
      
      BOOL IsDots (const std::wstring &strName)
      {
          return strName == L"." || strName == L".." ;
      }
      
      BOOL IsDir (const WIN32_FIND_DATA &fdFile)
      {
          return (fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-01-07
        • 1970-01-01
        • 2019-10-03
        • 1970-01-01
        • 2013-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多