Find and delete extensions (appex)

I am trying to make a script that finds and deletes appex files, the anoying extensions that get injected into Safari or Finder.
I’ve managed to get it working, but it’s kind of clumsy. I couldn’t get Finder to find appex files inside apps, so I used the find commnad. I can’t use -user to exclude Apple apps because the apps installed from the AppStore belong to root, just like Mail, Safari and others. So I used multiple grep strings.
Any suggestions on improving the script are welcomed.


set theList to (do shell script "find /Applications -name \"*.appex\" | grep -v \"Books.app\" | grep -v \"Notes.app\" | grep -v \"Mail.app\" | grep -v \"Home.app\" | grep -v \"Safari.app\" | grep -v \"FaceTime.app\" | grep -v \"Photos.app\" | grep -v \"Messages.app\" | grep -v \"VoiceMemos.app\" | grep -v \"Reminders.app\" | grep -v \"Calendar.app\" | grep -v \"iTunes.app\"")
display dialog ("The following .appex files were found:
" & theList) buttons {"Select appex files", "Cancel"}
if button returned of result = "Cancel" then
	return
else
	set thePrgs to paragraphs of theList
	set appexFiles to {}
	repeat with i from 1 to count of thePrgs
		set end of appexFiles to POSIX file (item i of thePrgs)
	end repeat
	tell application "Finder"
		repeat with currentFile in appexFiles
			set question to display dialog "Do you want to delete" & (POSIX path of currentFile) buttons {"Yes", "No", "Cancel"} default button 2
			set answer to button returned of question
			if answer is equal to "Yes" then
				try
					tell application "Finder"
						delete currentFile
					end tell
				on error
					display dialog ("File could not be deleted") buttons {"OK"}
				end try
			end if
			if answer is equal to "Cancel" then
				return
			end if
		end repeat
	end tell
end if

If you delete anything inside application bundles, you invalidate their code signature. In turn, that could lead them to fail to launch – newer versions of the OS are likely to check more often. It’s a pretty risky think to do. Why not just turn them off in System Preferences?

Because Safari extensions don’t show up there, try IINA https://iina.io

Can’t you turn it off in Safari Preferences?

They are not enabled by default, so far https://phxtechsol.com/2018/10/23/inside-safari-extensions-malicious-plugins-remain-on-mojave/
Apple says you should remove the application to uninstall the extension. I say I should just delete the extension. It’s for anyone to decide which makes more sense.
Any advice on the script?

It’s for anyone to decide what they do, but it’s not for anyone to decide which makes more sense. That depends on the facts. You might want to read this for an idea of potential problems you can cause yourself:

https://eclecticlight.co/2019/07/09/understanding-signature-checks-on-notarized-apps-in-mojave-10-14-5-1/

I can’t speak to your task’s end advisability, as I don’t really understand what you’re talking about, however, your method may affect numerous unintended and irreversible changes.

I believe this obtains your desired result, but proceed with caution:

set theList to (do shell script "find " & (path to applications folder)'s POSIX path's quoted form  & " -maxdepth 5 -type d -name '*.appex' | grep -Ev '(Books|Notes|Mail|Home|Safari|FaceTime|Photos|Messages|VoiceMemos|Reminders|Calendar|iTunes).app' ")

I would like to have a list of extensions hidden in applications. But for some reason your code is very slow. I think here you can do without the do shell script and get the best results. I especially would like to kill all the processes of the CoreSimulator of Xcode. How can I get rid of them?

It doesn’t work, your version returns this output:
“/Applications//Books.app/Contents/PlugIns/DiskSpaceEfficiency.appex
/Applications//Books.app/Contents/PlugIns/iBooksCacheDelete.appex
/Applications//Notes.app/Contents/PlugIns/com.apple.Notes.QuickLookExtension.appex
/Applications//Notes.app/Contents/PlugIns/com.apple.Notes.SharingExtension.appex
/Applications//Notes.app/Contents/PlugIns/com.apple.Notes.SpotlightIndexExtension.appex
/Applications//Home.app/Contents/PlugIns/HomeIntentExtension.appex
/Applications//IINA.app/Contents/PlugIns/OpenInIINA.appex
/Applications//Mail.app/Contents/PlugIns/MailStorageManagement.appex
/Applications//Mail.app/Contents/PlugIns/MailCacheDelete.appex
/Applications//Mail.app/Contents/PlugIns/MailShareExtension.appex
/Applications//Safari.app/Contents/PlugIns/CacheDeleteExtension.appex
/Applications//Safari.app/Contents/PlugIns/SafariQuickLookPreview.appex
/Applications//Safari.app/Contents/PlugIns/DiagnosticExtension.appex
/Applications//FaceTime.app/Contents/PlugIns/FaceTimeIntentsExtension.appex
/Applications//Photos.app/Contents/PlugIns/PhotosStorageExtension.appex
/Applications//Photos.app/Contents/PlugIns/PhotosSiriExtension.appex
/Applications//Messages.app/Contents/PlugIns/Messages Assistant Extension.appex
/Applications//Messages.app/Contents/PlugIns/Messages Share Extension.appex
/Applications//Messages.app/Contents/PlugIns/Messages Reply Extension.appex
/Applications//Messages.app/Contents/PlugIns/Messages Storage Management Extension.appex
/Applications//VoiceMemos.app/Contents/PlugIns/com.apple.VoiceMemos.SpotlightIndexExtension.appex
/Applications//VoiceMemos.app/Contents/PlugIns/VoiceMemosIntentsExtension.appex
/Applications//BetterZip.app/Contents/PlugIns/FinderSyncExtension.appex
/Applications//iTunes.app/Contents/PlugIns/iTunesCacheExtension.appex
/Applications//iTunes.app/Contents/PlugIns/iTunesStorageExtension.appex
/Applications//iTunes.app/Contents/PlugIns/TodayExtension.appex
/Applications//Reminders.app/Contents/PlugIns/RemindersShareExtension.appex
/Applications//Reminders.app/Contents/PlugIns/com.apple.RemindersNC.appex
/Applications//Calendar.app/Contents/PlugIns/com.apple.iCal.CalendarNC.appex”

My version returns only
“/Applications/IINA.app/Contents/PlugIns/OpenInIINA.appex
/Applications/BetterZip.app/Contents/PlugIns/FinderSyncExtension.appex”

What do you mean? What should I use instead?

I mean that (much more fast code- 8 seconds):


set list_of_apps to {"Books", "Notes", "Mail", "Home", "Safari", "FaceTime", "Photos", "Messages", "VoiceMemos", "Reminders", "Calendar", "iTunes"}

set appexFiles to {}
set appsPath to (path to applications folder) as string

repeat with theItem in list_of_apps
	set theBundle to (appsPath & theItem & ".app:Contents:") as alias
	getAllFiles(theBundle, appexFiles)
end repeat
appexFiles

on getAllFiles(theFolder, appexFiles)
	tell application "System Events"
		set fileList to every file of theFolder whose name extension is "appex"
		repeat with i from 1 to (count fileList)
			set end of appexFiles to item i of fileList
		end repeat
		set subFolders to folders of theFolder
		repeat with subFolderRef in subFolders
			my getAllFiles(subFolderRef, appexFiles)
		end repeat
	end tell
end getAllFiles

Those apps need to be excluded from the list. I want to delete the appex files in user installed apps, not in Apple preinstalled apps.

OK, try this (1 minute 56 seconds for processing totally 84 apps I have installed):


with timeout of 200 seconds
	set list_of_apps to paragraphs of (do shell script "find /Applications/ -name \"*.app\" -maxdepth 2| sed -e \"s/\\(.*\\)\\/\\([^\\/]*\\).app/\\2/g\"")
	set pre_Apps_List to {"Books", "Notes", "Mail", "Home", "Safari", "FaceTime", "Photos", "Messages", "VoiceMemos", "Reminders", "Calendar", "iTunes"}
	
	set appexFiles to {}
	set appsPath to (path to applications folder) as string
	
	repeat with theItem in list_of_apps
		if theItem is not in pre_Apps_List then
			try
				set theBundle to (appsPath & theItem & ".app:Contents:") as alias
				getAllFiles(theBundle, appexFiles)
			end try
		end if
	end repeat
	appexFiles
end timeout

on getAllFiles(theFolder, appexFiles)
	tell application "System Events"
		set fileList to every file of theFolder whose name extension is "appex"
		repeat with i from 1 to (count fileList)
			set end of appexFiles to item i of fileList
		end repeat
		set subFolders to folders of theFolder
		repeat with subFolderRef in subFolders
			my getAllFiles(subFolderRef, appexFiles)
		end repeat
	end tell
end getAllFiles

NOTE: I added to code try block, which does trick - it avoids automatically apps you can’t change contents (such as most of Apple apps and MicroSoft apps). Simply in such case command as alias fails and we use that fact

Congratulations, you’ve managed to make it longer and slower.

Yeah, it happens. :lol:
You can hardcode in filesList instead of Apple apps user installed apps, and use my first code which is faster.

NOTE: Need add try block to first script too

I edited my post, as there was an oversight on my part that you were looking for inverse results. The extended regex operand, -E, was added to enable the or symbols. The search’s depth was limited for better speed, however, additional caveats apply because of this; that number is arbitrary, as I don’t know how deep your objects are.

Thank you, that’s much better. maxdepth 5 works well for apps within a folder in Applications.
(POSIX path of (path to applications folder)) can be used instead of (path to applications folder)'s POSIX path’s quoted form
However, I realized that grep excludes all apps that end in the provided string. So, an app called CropPhotos.app is excluded because Photos.app is in the list.

In order to prevent unintentionally capturing words ending with the pattern, you could use find’s prune to spare out specific items, which starts becoming a bit convoluted, or just add the w option to the grep to make it function more literally.

set theList to (do shell script "find " & (path to applications folder)'s POSIX path & " -path 'cropPhotos.app' -prune -o -maxdepth 5 -name '*.appex' -print | grep -Ev '(Books|Notes|Mail|Home|Safari|FaceTime|Photos|Messages|VoiceMemos|Reminders|Calendar|iTunes).app' ")
set theList to (do shell script "find " & (path to applications folder)'s POSIX path's quoted form & " -maxdepth 5 -type d -name '*.appex' | grep -Evw '(Books|Notes|Mail|Home|Safari|FaceTime|Photos|Messages|VoiceMemos|Reminders|Calendar|iTunes).app' ")

That’s it! Thanks again for your help.