Removing an App?

I’m having problems removing an app from a folder. I built a method to recursively remove he contents of the app folder so that I can then remove the app. The app is another app I built for updating the main app to a new version. I need to delete the updater app at a certain point but it won’t work. However, no matter how I do it, the program always crashes when trying to remove the app folder, saying that the directory is not empty. Is there a better way to remove an app? TIA

Well, it would help if we saw your code and the crash log. Also important is the location of the app. If the app is in the app folder then you need to use AuthorizationMBS with a simple shellscript:

#!/bin/sh
if [ -d “$1” ]; then
rm -rf “$1”
fi

You should be catching your exceptions so that it doesn’t crash, and using API 2 methods so that you get exceptions when something goes wrong. Odds are a file is still in use or you don’t have permission. If the file is in use, I bet you need to wait for the updater to finish before trying to delete it. If you don’t have permission, something like what Beatrix suggested would be needed.

Your function might look something like

Function DeepDelete(Extends Target As FolderItem)
  If Target.IsFolder Then
    For Each Child As FolderItem In Target.Children(False)
      Child.DeepDelete
    Next
  End If
  Target.Remove
End Function

Then use it like:

Try
  UpdaterApp.DeepDelete
Catch Err As IOException
  // Do something to handle the error
End Try

I would not recommend putting the exception handling inside the method so that you can control its behavior on a case-by-case basis.

Anyway, Err will have more details about what went wrong, and you can stop the app from crashing.

Here is the method I’m using to try and delete the app: Maybe someone can look at it and tell me how to improve it so that it deletes the app. At the point where Im deleting the update app, it is not running or in use. Also, it’s not in the application folder so I should have permission to delete it. Here’s the method. Im passing in the folderItem named fFolder and returning boolean.

Dim fFileOrFolder As FolderItem
Dim sError As String = ""
Dim sFilesAndFoldersToClear() As String

' ------------------------------------------------------------
' Gather file and folder names under fDriveAndPath.
' ------------------------------------------------------------

for i as Integer = 1 to fFolder.Count
  sFilesAndFoldersToClear.Add fFolder.Item(i).name
next

if sFilesAndFoldersToClear.LastIndex >= 0 then
  for i as Integer = 0 to sFilesAndFoldersToClear.LastIndex
    
    fFileOrFolder = fFolder.child(sFilesAndFoldersToClear(i))
    if fFileOrFolder <> Nil then
      
      if fFileOrFolder.directory then
        
        If Not RemoveFolderAndContents(fFileOrFolder) Then 
          sError = "Error Call to RemoveFolder"
          
        Else
          
          ' ------------------------------------------------------------
          'Then Remove the folder
          if fFileOrFolder.Locked then fFileOrFolder.Locked = False
          
          Try
            fFileOrFolder.Remove
          Catch Error As IOException
            sError = "Failed to remove fFileOrFolder."
          end try
          
        end if
        
      else
        
        ' ------------------------------------------------------------
        ' If a file, remove it.
        
        if fFileOrFolder.Locked then fFileOrFolder.Locked = False
        
        Try
          fFileOrFolder.Remove
        Catch Error As IOException
          sError = "Failed to remove fFileOrFolder."
        end try
        
      end if
      
    else
      sError = "fFileOrFolder is nil."
    end if
    
    if sError <> "" then exit for
  next ' for i as Integer = 0 to sFilesAndFoldersToClear.LastIndex
  
end if

If sError = "" Then
  Return True
Else
  Return False
end if

Any suggestions for what I could add? Thanks for the help.

The first thing to do is do switch 0 and sFilesAndFoldersToClear.LastIndex

Then the error message would be important.

It’s running just fine there. That’s not where the problem is happening. The problem happens when you check to see if it’s a folder and an app is considered a folder so it tries to remove it with stuff inside.

Which code crashes with which error message? Is it an exception or a hard crash?

It’s in the chunk of code where it has determined that it is a folder and then tries to remove it.

    
        Try
          fFileOrFolder.Remove
        Catch Error As IOException
          sError = "Failed to remove fFileOrFolder."
        end try

Then I get an error code 107 that the directory is not empty.

I would just use the code I already suggested in Removing an App? - #3 by Thom_McGrath. I’m sorry to be harsh, but your code is extremely verbose and much of it unnecessary. Why are you collecting the contents into an array of strings? If you’re going to do that at all why is it not an array of FolderItems, when you’re just going to use the name in the next loop to get a new FolderItem? Why are you writing error messages if you’re just going to discard them and return a boolean?

The only functional difference between yours and mine, aside from performance, is that yours will keep going deleting anything it can delete, whereas mine will stop at the first error. This is kind of a personal preference thing, but I’m not sure how it’d make much of a difference considering you’re discarding your error info anyway.

I didn’t intentionally ignore it. It was just a bit cryptic to read. After looking back at it again, Im going to give it a shot. The only reason my method is written that way is because it is based on a method from MBS on one of their forums from 2015. As for the error, I only wrote it that way so If I wanted to turn on debugging I could output the message.

Thanks for your help. I’ll give yours a shot.

Gold Star! It finally works. It successfully deleted the app. Thank you so much.

BTW, any reason why you’re not using the FolderItem. RemoveFolderAndContents Xojo’s method?

I had no idea that existed. What an obtuse method name. I’m sure it works fine, I’m just not sure why it’s not a parameter on Remove. Like Function Remove(Recursive As Boolean = False). I wonder if it works if called on a file. I’d hope so, so you wouldn’t need to write your own wrapper just to switch between the two, but I could see it not working given it’s very specific name.