Hi guys,
I’m creating a small uninstaller utility for work, and I would really require some assistance while trying to detect and remove files. I need to delete multiple files from various locations on the hard drive. So here are a few instances that I’ve been playing around with, but all failed:
Current Try:
on Deleter()
set userName to (do shell script “logname”)
set t to POSIX path of file “/Applications/Remove This Application.app”
do shell script "rm -R " & t
end Deleter
Previous Try:
on Deleter()
–do shell script “thisUser=logname”
–set thisUser to do shell script “logname”
-- Setting a variable to gather a string of the application folder
set applicationsPath to (path to applications folder) as string
--Setting variable to gather a string of the
set userChoice to applicationsPath & "test.txt" as string
--display dialog "userChoice: " & (userChoice as string)
set posixPath to POSIX path of userChoice as string
-- Setting a variable to gather a string of the system folder
set systemPath to (path to system folder) as string
set newChoice to systemPath & "Library:test.txt"
--display dialog "posixPath: " & (posixPath as string)
set newPosix to POSIX path of newChoice as string
try
display dialog "quoted pth: " & (quoted form of posixPath as string) & (quoted form of newPosix as string)
do shell script "rm -R " & quoted form of posixPath with administrator privileges
--display dialog "quoted pth: " & (quoted form of newPosix as string)
do shell script "rm -R " & quoted form of newPosix with administrator privileges
--delete (file thisUser) + "/Desktop/test.txt"
on error
--display dialog ""
end try
end Deleter
I have written some bash shell scripts to already do this, however, my goal is to make a double-clickable utility that would do pretty much the same thing. Here is a code-snippet from my shell script:
THIS_USER=logname
echo “”
echo “”
echo “Uninstaller Utility…”
echo “”
if [ -d “/Applications/Test Application.app” ]; then
sudo rm -R “/Applications/Test Application.app”
else
echo "Could not find Test Application.app in /Applications...."
fi
I also need this uninstaller utility to run on various Mac machines, so the way that applescript would search for the username would have to be dynamic, as shown in m BASh shell script using the ‘logname’ feature. I would also need to implement “sudo” to force-delete the application on certain machines, or would the “with administrator privileges” be sufficient?
Thanks for all your help guys and God Bless you!
Ben.
Hi Ben,
your scripts don’t work because you use the wrong path type
AppleScript works only with HFS path (colon separated).
Shell scripts work only with POSIX paths (slash separated).
Try this:
on Deleter()
set t to POSIX path of (path to applications folder) & "Remove This Application.app"
do shell script "rm -R " & quoted form of t
end Deleter
path to applications folder returns → alias “Mac HD:Applications:”
POSIX path of coerces the alias and the literal string to → /Applications/Remove This Application.app
quoted form quotes the path to handle space characters properly → ‘/Applications/Remove This Application.app’
Thanks StefanK for your help,
That logic seems to work, however, my question would be:
How would it work when I have to delete files in the “/Library/Receipts” folder, and the “/System/Library/Extensions” folder, and many other folders that my application installs files to? As you can see there are subfolders within the primary folders, so I can’t necessarily use (path to applications folder) or (path to system folder) can I? Would I be able to use (path to system:library folder) or something like that?
Thanks,
Ben.
POSIX paths don’t care about the name of the startup disk,
so you can “hard-code” the paths and they are portable anyway like
/Library/Receipts/
/System/Library/Extensions/
for the main library and the system library you need root privileges to delete files.
Don’t use sudo in the do shell script lines, add just with administrator privileges
then the user must enter an admin password
Cool, so an example would be:
set t to POSIX path of (path to applications folder) & “Remove This Application.app”
set x to POSIX path of (path to library folder) & “/Receipts/Remove This Package.pkg”
set y to POSIX path of (path to system folder) & “/Library/Extensions/Remove This Extension.kext”
and similarly:
do shell script "rm -R " & quoted form of t with administrator privileges
do shell script "rm -R " & quoted form of x with administrator privileges
do shell script "rm -R " & quoted form of y with administrator privileges
And so on. Is this correct?
why not
do shell script "rm -R '/Applications/Remove This Application.app'" with administrator privileges
do shell script "rm -R '/Library/Receipts/Remove This Package.pkg'" with administrator privileges
do shell script "rm -R '/System/Library/Extensions/Remove This Extension.kext'" with administrator privileges
the slash at the beginning of the literal string is not necessary
set x to POSIX path of (path to library folder) & "/Receipts/Remove This Package.pkg"
because a path to folder command coerced to POSIX path ends always with a slash
So, I only have to do this:
do shell script “rm -R ‘/Applications/Remove This Application.app’” with administrator privileges
do shell script “rm -R ‘/Library/Receipts/Remove This Package.pkg’” with administrator privileges
do shell script “rm -R ‘/System/Library/Extensions/Remove This Extension.kext’” with administrator privileges
And I don’t need to do this anymore as the first part kind of overrides the following step?
set x to POSIX path of (path to library folder) & “/Receipts/Remove This Package.pkg”
Thanks again for your help dude, and sorry for the multitude of questions because I want to make sure I have it right before going back into code.
You need only the three shell script lines, these work on every Mac.
My note was only an explanation, the path to line is not needed
Thanks so much man! It worked. However, if it comes across existing files, it will stop and give me an error that the file doesn’t exist. I’m currently using this method for all my files and directories:
do shell script “rm -R ‘/Library/ReceiptsSomethingToDelete.pkg’” with administrator privileges
How do I test if it exists and then move on if it doesn’t to the next statement?
a try block ignores the error messages.
You can also use a repeat loop
property filesToDelete : {"/Applications/Remove This Application.app", "/Library/Receipts/Remove This Package.pkg", "/System/Library/Extensions/Remove This Extension.kext"}
repeat with oneFile in filesToDelete
try
do shell script "rm -R " & quoted form of oneFile with administrator privileges
end try
end repeat
Sweet, thanks for your help man. However, after coding some more last night, I came up with this:
set testSoftware to POSIX path of (path to applications folder) & “Test This Software.app”
try
alias testSoftware
do shell script "rm -R " & quoted form of testSoftware with administrator privileges
end try
set newPkg to POSIX path of (path to library folder) & “Receipts/new.pkg”
try
alias newPkg
do shell script "rm -R " & quoted form of newPkg with administrator privileges
end try
This seems to work too…what do you think of this code? The alias command does the testing, however, do you think I will encounter further implications with this method, or is it just as good as your method with the loop?
Thanks,
Ben.
your code will never reach the do shell script line, because
alias [POSIX path] causes always an error.
As mentioned above AppleScript works only with HFS paths.
Anyway the alias check is not needed. If the file doesn’t exist, the shell line throws the error
Well, the alias command seems to be working, as it skips over the missing files and works it’s way to the existing files. However, you think the loop method you provided is fool-proof? And I can store that list or “array” as a property of all my paths to cycle through?
Yes, the repeat loop is fool-proof.
You can define a property containing a list of literal strings paths unless you use relative paths with path to. Don’t do this!
PS:
alias "/Applications/Utilities/"
--> AppleScript RunTime Error: File /Applications/Utilities/ wasn't found.
Awesome, okay I tried defining my list of values in a property as such:
property filesToDelete : {“/blahblahblah/blahblah.blah”, “etcetc/etcetc/etcetc.etc”, “and so on…”} However, I get this error: Expected “end” but found “property”. Do I need an end tag for the property field?
No, but place the property at the beginning of the script on the top level,
not within a handler
Awesome, it worked! Thanks so much. I have one more question…the application I’m trying to delete (by deleting all these files), could be running at the time. How do I check whether the application is running, and if it is running, then close it first before I execute my delete commands?
Thanks,
Ben.
-- Tiger
tell application "System Events" to set AppIsRunning to exists process "myApp"
if AppIsRunning then quit application "myApp"
-- Leopard only
if application "myApp" is running then quit application "myApp"
Is there a “universal” method between Panther, Tiger, and Leopard, or will the Tiger method that you mentioned work between all three OS’s, as I need the same uninstaller utility to run on all three OS’s (Intel and PPC)?
The first way works also in Panther