Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Failure to remove folders after using CFileDialog DoModal

Failure to remove folders after using CFileDialog DoModal

Scheduled Pinned Locked Moved C / C++ / MFC
10 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Still learning how to code
    wrote on last edited by
    #1

    I picked up a function RecursiveDelete on the internet, as I needed to erase all files and folders on an SD card (as part of a larger project). I was having problems insofar as the function would fail on removing the folders after CFileDialog DoModal - there were two nested folders, the deepest failing with code 32 ("in use by another proicess") and the shallowest with 145 ("folder not empty" - expected !) However, if I call the function BEFORE the DoModal, then everything works fine. I have extracted the relevent code into a simpler project and it still fails Perhaps some kind soul can throw some light on why this is so !!

    CFileDialog dlgFileBrowse(true);

    UINT uiFileBrowseDlgRC;
    

    // OK here
    RecursiveDelete("F:"); // 20150615

    //
    uiFileBrowseDlgRC = dlgFileBrowse.DoModal();

    // FAILS HERE - YES

    void CDeleteFolderTestDlg::RecursiveDelete(CString szPath)
    {
    CFileFind ff;
    BOOL bResult;
    CString path = szPath;

    if(path.Right(1) != '\\\\')	
    	path += '\\\\';			
    
    path += "\*.\*";
    
    bResult = ff.FindFile(path);
    BOOL bItemDelete;
    DWORD dwLastError;
    CString szFilePath;
    
    while(bResult)
    {
    	bResult = ff.FindNextFile();
    	if (!ff.IsDots() && !ff.IsDirectory())
    	{
    		szFilePath = ff.GetFilePath();
    		bItemDelete = DeleteFile(szFilePath);
    		if(!bItemDelete)
    			dwLastError = GetLastError();
    	}
    	else if (ff.IsDirectory() && !ff.IsDots())	
    	{
    		path = ff.GetFilePath();
    
    		RecursiveDelete(path);
    
    		bItemDelete = RemoveDirectory(path);
    		if(!bItemDelete)
    			dwLastError = GetLastError();
    	}
    }
    

    }

    // RecursiveDelete("F:");

    Doug

    F J D 3 Replies Last reply
    0
    • S Still learning how to code

      I picked up a function RecursiveDelete on the internet, as I needed to erase all files and folders on an SD card (as part of a larger project). I was having problems insofar as the function would fail on removing the folders after CFileDialog DoModal - there were two nested folders, the deepest failing with code 32 ("in use by another proicess") and the shallowest with 145 ("folder not empty" - expected !) However, if I call the function BEFORE the DoModal, then everything works fine. I have extracted the relevent code into a simpler project and it still fails Perhaps some kind soul can throw some light on why this is so !!

      CFileDialog dlgFileBrowse(true);

      UINT uiFileBrowseDlgRC;
      

      // OK here
      RecursiveDelete("F:"); // 20150615

      //
      uiFileBrowseDlgRC = dlgFileBrowse.DoModal();

      // FAILS HERE - YES

      void CDeleteFolderTestDlg::RecursiveDelete(CString szPath)
      {
      CFileFind ff;
      BOOL bResult;
      CString path = szPath;

      if(path.Right(1) != '\\\\')	
      	path += '\\\\';			
      
      path += "\*.\*";
      
      bResult = ff.FindFile(path);
      BOOL bItemDelete;
      DWORD dwLastError;
      CString szFilePath;
      
      while(bResult)
      {
      	bResult = ff.FindNextFile();
      	if (!ff.IsDots() && !ff.IsDirectory())
      	{
      		szFilePath = ff.GetFilePath();
      		bItemDelete = DeleteFile(szFilePath);
      		if(!bItemDelete)
      			dwLastError = GetLastError();
      	}
      	else if (ff.IsDirectory() && !ff.IsDots())	
      	{
      		path = ff.GetFilePath();
      
      		RecursiveDelete(path);
      
      		bItemDelete = RemoveDirectory(path);
      		if(!bItemDelete)
      			dwLastError = GetLastError();
      	}
      }
      

      }

      // RecursiveDelete("F:");

      Doug

      F Offline
      F Offline
      Freak30
      wrote on last edited by
      #2

      I assume that the CFileDialog object contains a handle to the directory once it's opened and that the handle is freed when the dialog object is destroyed. You could try the following:

      CFileDialog * dialog = new CFileDialog(true);
      dialog->DoModal();
      delete dialog;
      RecursiveDelete("F:");

      Alternatively you could try:

      {
      CFileDialog dialog(true);
      dialog.DoModal();
      }
      RecursiveDelete("F:");

      The good thing about pessimism is, that you are always either right or pleasently surprised.

      J S 2 Replies Last reply
      0
      • S Still learning how to code

        I picked up a function RecursiveDelete on the internet, as I needed to erase all files and folders on an SD card (as part of a larger project). I was having problems insofar as the function would fail on removing the folders after CFileDialog DoModal - there were two nested folders, the deepest failing with code 32 ("in use by another proicess") and the shallowest with 145 ("folder not empty" - expected !) However, if I call the function BEFORE the DoModal, then everything works fine. I have extracted the relevent code into a simpler project and it still fails Perhaps some kind soul can throw some light on why this is so !!

        CFileDialog dlgFileBrowse(true);

        UINT uiFileBrowseDlgRC;
        

        // OK here
        RecursiveDelete("F:"); // 20150615

        //
        uiFileBrowseDlgRC = dlgFileBrowse.DoModal();

        // FAILS HERE - YES

        void CDeleteFolderTestDlg::RecursiveDelete(CString szPath)
        {
        CFileFind ff;
        BOOL bResult;
        CString path = szPath;

        if(path.Right(1) != '\\\\')	
        	path += '\\\\';			
        
        path += "\*.\*";
        
        bResult = ff.FindFile(path);
        BOOL bItemDelete;
        DWORD dwLastError;
        CString szFilePath;
        
        while(bResult)
        {
        	bResult = ff.FindNextFile();
        	if (!ff.IsDots() && !ff.IsDirectory())
        	{
        		szFilePath = ff.GetFilePath();
        		bItemDelete = DeleteFile(szFilePath);
        		if(!bItemDelete)
        			dwLastError = GetLastError();
        	}
        	else if (ff.IsDirectory() && !ff.IsDots())	
        	{
        		path = ff.GetFilePath();
        
        		RecursiveDelete(path);
        
        		bItemDelete = RemoveDirectory(path);
        		if(!bItemDelete)
        			dwLastError = GetLastError();
        	}
        }
        

        }

        // RecursiveDelete("F:");

        Doug

        J Offline
        J Offline
        Jochen Arndt
        wrote on last edited by
        #3

        When dlgFileBrowse.DoModal() returns, the dialog window has been closed but the object itself still exists and may have open file handles. These should be closed by the destructor of the browse dialog. I have not tested this but it seems a probable reason. So you should try to call your delete function after the browse dialog object is destroyed:

        UINT uiFileBrowseDlgRC;
        // This block ensures that dlgFileBrowse goes out of scope
        // before calling the delete function.
        {
        CFileDialog dlgFileBrowse(true);
        uiFileBrowseDlgRC = dlgFileBrowse.DoModal();
        }
        // This should work now.
        RecursiveDelete("F:");

        Alternatively you can create the dialog using new and delete it before calling RecursiveDelete.

        S 1 Reply Last reply
        0
        • F Freak30

          I assume that the CFileDialog object contains a handle to the directory once it's opened and that the handle is freed when the dialog object is destroyed. You could try the following:

          CFileDialog * dialog = new CFileDialog(true);
          dialog->DoModal();
          delete dialog;
          RecursiveDelete("F:");

          Alternatively you could try:

          {
          CFileDialog dialog(true);
          dialog.DoModal();
          }
          RecursiveDelete("F:");

          The good thing about pessimism is, that you are always either right or pleasently surprised.

          J Offline
          J Offline
          Jochen Arndt
          wrote on last edited by
          #4

          Snap. You beat me by seconds with the solution.

          1 Reply Last reply
          0
          • F Freak30

            I assume that the CFileDialog object contains a handle to the directory once it's opened and that the handle is freed when the dialog object is destroyed. You could try the following:

            CFileDialog * dialog = new CFileDialog(true);
            dialog->DoModal();
            delete dialog;
            RecursiveDelete("F:");

            Alternatively you could try:

            {
            CFileDialog dialog(true);
            dialog.DoModal();
            }
            RecursiveDelete("F:");

            The good thing about pessimism is, that you are always either right or pleasently surprised.

            S Offline
            S Offline
            Still learning how to code
            wrote on last edited by
            #5

            Freak30 wrote:

            CFileDialog * dialog = new CFileDialog(true); dialog->DoModal(); delete dialog; RecursiveDelete("F:");

            Hi Freak30, Tried the dynamic allocation of the CFileDialog (and deletion before the call to RecursiveDelete)as you suggested, but still get the same result (files deleted, but deepest folder gets RC=32 and shallowest gets RC=145. Very confused !!

            Doug

            1 Reply Last reply
            0
            • J Jochen Arndt

              When dlgFileBrowse.DoModal() returns, the dialog window has been closed but the object itself still exists and may have open file handles. These should be closed by the destructor of the browse dialog. I have not tested this but it seems a probable reason. So you should try to call your delete function after the browse dialog object is destroyed:

              UINT uiFileBrowseDlgRC;
              // This block ensures that dlgFileBrowse goes out of scope
              // before calling the delete function.
              {
              CFileDialog dlgFileBrowse(true);
              uiFileBrowseDlgRC = dlgFileBrowse.DoModal();
              }
              // This should work now.
              RecursiveDelete("F:");

              Alternatively you can create the dialog using new and delete it before calling RecursiveDelete.

              S Offline
              S Offline
              Still learning how to code
              wrote on last edited by
              #6

              Apologies for the double posting - thought that the original hadn't worked !! Tried dynamic allocation of dialog and subsequent deletion before calling RecursiveDelete as Freak32 suggested, but get exactly the same result. Wierd !! Could someone else run this and see if they can reproduce this behaviour ? (Driving me mad !)

              Doug

              J 1 Reply Last reply
              0
              • S Still learning how to code

                Apologies for the double posting - thought that the original hadn't worked !! Tried dynamic allocation of dialog and subsequent deletion before calling RecursiveDelete as Freak32 suggested, but get exactly the same result. Wierd !! Could someone else run this and see if they can reproduce this behaviour ? (Driving me mad !)

                Doug

                J Offline
                J Offline
                Jochen Arndt
                wrote on last edited by
                #7

                A quick web research brought some more infomation. CFileDialog will change the current working directory which may lead to the locked directory. So you may try to also set the current working directory to something else (e.g. to another drive) before calling your delete function:

                SetCurrentDirectory(_T("C:\\"));

                S 1 Reply Last reply
                0
                • J Jochen Arndt

                  A quick web research brought some more infomation. CFileDialog will change the current working directory which may lead to the locked directory. So you may try to also set the current working directory to something else (e.g. to another drive) before calling your delete function:

                  SetCurrentDirectory(_T("C:\\"));

                  S Offline
                  S Offline
                  Still learning how to code
                  wrote on last edited by
                  #8

                  Hi Jochen, Just done a quick check (I actually used _chdir) and that SEEMS to have fixed it. Hopefully, when I migrate these changes to my REAL code, it will stay fixed ! Many thanks to everybody who helped with this - wierd problem, eh ?

                  Doug

                  J 1 Reply Last reply
                  0
                  • S Still learning how to code

                    Hi Jochen, Just done a quick check (I actually used _chdir) and that SEEMS to have fixed it. Hopefully, when I migrate these changes to my REAL code, it will stay fixed ! Many thanks to everybody who helped with this - wierd problem, eh ?

                    Doug

                    J Offline
                    J Offline
                    Jochen Arndt
                    wrote on last edited by
                    #9

                    Thank you for your feedback. _chdir will internally call SetCurrentDirectory. A directory that is selected as current directory is treated like a file in use and can't be deleted. It seems that the file dialog selects the actually shown directory as the current one and does not change it back. There is an OFN_NOCHANGEDIR file dialog option to restore the original directory but that is ignored for opening files (only supported for the Save as dialog).

                    1 Reply Last reply
                    0
                    • S Still learning how to code

                      I picked up a function RecursiveDelete on the internet, as I needed to erase all files and folders on an SD card (as part of a larger project). I was having problems insofar as the function would fail on removing the folders after CFileDialog DoModal - there were two nested folders, the deepest failing with code 32 ("in use by another proicess") and the shallowest with 145 ("folder not empty" - expected !) However, if I call the function BEFORE the DoModal, then everything works fine. I have extracted the relevent code into a simpler project and it still fails Perhaps some kind soul can throw some light on why this is so !!

                      CFileDialog dlgFileBrowse(true);

                      UINT uiFileBrowseDlgRC;
                      

                      // OK here
                      RecursiveDelete("F:"); // 20150615

                      //
                      uiFileBrowseDlgRC = dlgFileBrowse.DoModal();

                      // FAILS HERE - YES

                      void CDeleteFolderTestDlg::RecursiveDelete(CString szPath)
                      {
                      CFileFind ff;
                      BOOL bResult;
                      CString path = szPath;

                      if(path.Right(1) != '\\\\')	
                      	path += '\\\\';			
                      
                      path += "\*.\*";
                      
                      bResult = ff.FindFile(path);
                      BOOL bItemDelete;
                      DWORD dwLastError;
                      CString szFilePath;
                      
                      while(bResult)
                      {
                      	bResult = ff.FindNextFile();
                      	if (!ff.IsDots() && !ff.IsDirectory())
                      	{
                      		szFilePath = ff.GetFilePath();
                      		bItemDelete = DeleteFile(szFilePath);
                      		if(!bItemDelete)
                      			dwLastError = GetLastError();
                      	}
                      	else if (ff.IsDirectory() && !ff.IsDots())	
                      	{
                      		path = ff.GetFilePath();
                      
                      		RecursiveDelete(path);
                      
                      		bItemDelete = RemoveDirectory(path);
                      		if(!bItemDelete)
                      			dwLastError = GetLastError();
                      	}
                      }
                      

                      }

                      // RecursiveDelete("F:");

                      Doug

                      D Offline
                      D Offline
                      David Crow
                      wrote on last edited by
                      #10

                      Still learning how to code wrote:

                      I picked up a function RecursiveDelete on the internet, as I needed to erase all files and folders on an SD card...

                      Why not just use SHFileOperation() with the FO_DELETE operation?

                      "One man's wage rise is another man's price increase." - Harold Wilson

                      "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

                      "You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups