Try statements acting up in AppleScript - applescript

I'm trying to figure out try statements in AppleScript. I got it to compile, but it doesn't do what I want it to do.
try
do shell script "cat " & passData
on error
display dialog "Create a password to protect this file. After creating the password, you will need to enter it every time in order to access the app." default answer "" buttons {"Cancel", "OK"} default button 2 with hidden answer
set pass1 to text returned of result
display dialog "Confirm the password you entered." default answer "" buttons {"Cancel", "OK"} default button 2 with hidden answer
set pass2 to text returned of result
if pass1 is pass2 then
set setPass to pass2
set passSalt to random number from 10000000 to 99999999
do shell script "echo " & setPass & " | shasum -a 512 | awk '{print $1}'"
set passHash to result
set cHash1 to random number from 10 to 25
set cHash2 to random number from 26 to 50
set cHash3 to random number from 51 to 75
set cHash4 to random number from 76 to 99
set hBlock1 to characters cHash1 through cHash2 of passHash
set hBlock2 to characters cHash3 through cHash4 of passHash
set finalHash to hBlock1 & passHash & hBlock2
do shell script "echo " & passSalt & return & cHash1 & return & cHash2 & return & cHash3 & return & cHash4 & " > " & passData
do shell script "echo " & finalHash & " > " & appPath & "Contents/Resources/FinalHash.txt"
else
display dialog "The passwords didn't match. Restart the application and try again." buttons {"OK"} default button 1
quit
end if
quit
end try
I want the application to quit if the text entered in the first and second dialog boxes don't match, but it just goes on to the rest of the code. I also want the application to quit after it does all the hashing mumbo jumbo if the text entered in the boxes match, but it doesn't do that either. How can I fix this? I suspect it has something to do with the try statements.
Edit: when I said it goes on to the rest of the code, I meant when I exported it as an app. It works correctly in the editor but in the app it continues to the rest of the code.

You put an end try on the end of your script, but there's no opening try to close off.
In the code below I've removed the end try. In addition to that, I've added tell application "finder" and end tell to prevent your script editor from quiting.
Tried it and it works fine here.
tell application "Finder"
display dialog "Create a password to protect this file. After creating the password, you will need to enter it every time in order to access the app." default answer "" buttons {"Cancel", "OK"} default button 2 with hidden answer
set pass1 to text returned of result
display dialog "Confirm the password you entered." default answer "" buttons {"Cancel", "OK"} default button 2 with hidden answer
set pass2 to text returned of result
if pass1 is pass2 then
set setPass to pass2
set passSalt to random number from 10000000 to 99999999
do shell script "echo " & setPass & " | shasum -a 512 | awk '{print $1}'"
set passHash to result
set cHash1 to random number from 10 to 25
set cHash2 to random number from 26 to 50
set cHash3 to random number from 51 to 75
set cHash4 to random number from 76 to 99
set hBlock1 to characters cHash1 through cHash2 of passHash
set hBlock2 to characters cHash3 through cHash4 of passHash
set finalHash to hBlock1 & passHash & hBlock2
do shell script "echo " & passSalt & return & cHash1 & return & cHash2 & return & cHash3 & return & cHash4 & " > " & passData
do shell script "echo " & finalHash & " > " & appPath & "Contents/Resources/FinalHash.txt"
else
display dialog "The passwords didn't match. Restart the application and try again." buttons {"OK"} default button 1
quit
end if
end tell

Never mind, I found out a way that works! :)
Between the try and on error, I added set quitFunction to "0". Then between the on error and end try I added set quitFunction to 1. After the end try I made the script test if the variable quitFunction is 1. If it is, it quits and if it isn't, it doesn't quit.

Related

Need help to create gui with buttons to select Shell Scripts via Script editor in MacOs Monterey/Ventura

Im new to creating scripts for Apple (MacOsx Ventura)…
I would like to create an AppleScript with serveral buttons 3 to 9 depending on what Shell script I want to create… What I have now works in Mac terminal with selecting by pressing 1, 2, 3, etc… I like the look of Buttons… this method looks good so… but how to select the option and running a shell script or applescript after clicking ok
set optionList to {“Shell Script-1”, " Shell Script-2", " Applescript-1", " Applescript-2"}
set chosenScript to choose from list optionList with prompt “Choose a Script to run:”
if chosenScript is false then
error number -128 (* User cancelled *)
else
set chosenScript to chosenScript’s item 1 (* extract choice from list *)
end if
display dialog "You chose a " & chosenScript & “!”
With choose from list it's pretty easy to get the selected item by adding index prefices.
set optionList to {"1 Shell Script-1", "2 Shell Script-2", "3 Applescript-1", "4 Applescript-2"}
set chosenScript to choose from list optionList with prompt "Choose a Script to run:"
if chosenScript is false then
error number -128 (* User cancelled *)
else
set chosenIndex to word 1 of (chosenScript's item 1) as integer
end if
display dialog "You chose a " & text 3 thru -1 of item chosenIndex of optionList & "!"
You can even press the index number and then return.
I found what I needed, it maybe not be buttons, but it has selectable options.. I got it with help from ChatGPT
set scriptsList to {"Enable SMB", "Disable SMB", "Create a Local User", "Delete a Local User", "Application Install", "Student Password Fix"}
choose from list scriptsList with title "Script Selection" with prompt "Select a script:"
if the result is not false then
set userChoice to item 1 of result
if userChoice is "Enable SMB" then
set scriptPath to "/Volumes/Ventoy/Scripts/MAC_Scripts/Enable-SMB.zsh"
do shell script "open -a Terminal -sh " & quoted form of scriptPath
else if userChoice is "Disable SMB" then
set scriptPath to "/Volumes/Ventoy/Scripts/MAC_Scripts/Disable-SMB.zsh"
do shell script "open -a Terminal -sh " & quoted form of scriptPath
else if userChoice is "Create a Local User" then
set scriptPath to "/Volumes/Ventoy/Scripts/MAC_Scripts/Create-Local-Account.scpt"
do shell script "osascript " & quoted form of scriptPath
else if userChoice is "Delete a Local User" then
set scriptPath to "/Volumes/Ventoy/Scripts/MAC_Scripts/User-Delete.zsh"
do shell script "open -a Terminal -sh " & quoted form of scriptPath
else if userChoice is "Application Install" then
set scriptPath to "/Volumes/Ventoy/Scripts/MAC_Scripts/Applications-Policies.zsh"
do shell script "open -a Terminal -sh " & quoted form of scriptPath
else if userChoice is "Student Password Fix" then
set scriptPath to "/Volumes/Ventoy/Scripts/MAC_Scripts/Student_Password_Fix.zsh"
do shell script "open -a Terminal -sh " & quoted form of scriptPath
end if
end if

How to Mount Multiple EFI Partitions?

I’m trying to create an Applescript-Objc to mount multiple EFI partitions, but I’m not able to mount the EFI partitions on external drives only those on the internal disk,
what I've done so far is this:
set a to do shell script "diskutil list | grep EFI | grep -o -e disk[0-9]s[0-9]"
set b to do shell script "diskutil info " & a & " | awk '/Identifier/' | grep -o -e disk[[:digit:]]*"
set c to do shell script "diskutil info " & b & "| grep 'Media Name' | awk /'Name:/{print$5,$6}'"
choose from list c with prompt "Multiple EFI partitions found:"
display alert "Do you want to mount the EFI partition?" buttons {"Yes", "No"} default button 1
set response to button returned of the result
if response = "Yes" then
do shell script "diskutil mount " & a with administrator privileges
display alert result
end if
Note: when asked the user I want the disk name to be displayed and not something like: ''disk0s1''
Thanks in advance!
I wrote an EFI mount/unmount utility applet a while ago that uses an NSAlert with a combo box to try to avoid the death by dialog typical with AppleScripts. I extracted the script from that and added disk names to the initial dialog - the alert stuff makes it a bit longer than your snippet, but there should be something in there you can use:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
property alertHeader : " --- CAUTION ---" & return & "This utility works with EFI boot partitions -" & return & "Administrator authorization will be required."
property resources : "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/"
property leadText : " "
property identifiers : missing value -- this will be a list of the EFI partition identifiers, e.g. {disk0s1}
on run -- example can be run as app and from Script Editor
if current application's NSThread's isMainThread() as boolean then
doStuff()
else
my performSelectorOnMainThread:"doStuff" withObject:(missing value) waitUntilDone:true
end if
end run
on doStuff() -- the main stuff
set theDisks to setup() -- set up properties and get disks with EFI partitions, e.g. {/dev/disk0}
set reply to {button:missing value, answer:""} -- preset a previous empty dialog result
repeat -- forever
set theAnswer to answer of reply -- use previous
set reply to (showAlert given settings:{title:"EFI [un]Mounter", message:alertHeader, information:"EFI partitions have been found on the following disks:" & return & return & theDisks & return & "The EFI partition of the specified disk will be [un]mounted." & return & "Enter the disk identifier or select one from the menu:", answer:theAnswer, icon:(resources & "AlertCautionIcon.icns"), buttons:{"Cancel", "Mount", "Unmount", "More Info"}})
if button of reply is "Cancel" then error number -128
set diskID to checkID(answer of reply)
if diskID is not missing value then -- found it
if button of reply is "More Info" then
set reply to moreInfo(answer of reply) -- result of the moreInfo dialog
if button of reply is not "Change" then exit repeat
else
exit repeat
end if
else -- try again
beep
set answer of reply to ""
end if
end repeat
processEFI(button of reply, diskID)
end doStuff
to processEFI(command, diskID) -- mount or unmount the specified disk - admin authorization will be needed
log diskID
try
set command to (do shell script "echo " & command & " | tr [:upper:] [:lower:]")
if command is not in {"mount", "unmount"} then error "The processEFI handler received an invalid command."
set theResult to (do shell script "diskutil " & command & " /dev/" & diskID with administrator privileges)
if command is "mount" then tell application "Finder" -- show it
make new Finder window to ("/Volumes/EFI" as POSIX file)
activate
end tell
display notification theResult
delay 2
on error errmess
log errmess
showAlert given settings:{title:"EFI [un]Mounter", message:return & "There was an error processing the partition.", information:errmess, icon:(resources & "AlertCautionIcon.icns")}
end try
end processEFI
on moreInfo(diskID) -- get more information about the specified disk identifier
set infoText to ""
set diskName to (do shell script "diskutil info " & diskID & " | grep 'Media Name' | awk '{print substr($0,index($0,$5))}'")
if diskName is "" then
set diskName to "the following disk"
else
set diskName to "disk " & quoted form of diskName
end if
repeat with aParagraph in paragraphs of (do shell script "diskutil list " & diskID)
if aParagraph starts with leadText then -- trim information text
if (paragraph -2 of infoText does not start with leadText) then set infoText to infoText & leadText & trimWhitespace(text 1 thru -1 of contents of aParagraph) & return
else if aParagraph does not start with " #:" then -- don't include header text
if length of aParagraph is less than 56 then
set infoText to infoText & aParagraph & return
else -- trim description text
set infoText to infoText & space & space & space & text 1 thru 6 of aParagraph & tab & trimWhitespace(text 7 thru 56 of aParagraph)
set infoText to infoText & return
end if
end if
end repeat
set reply to (showAlert given settings:{title:"EFI [un]Mounter", message:alertHeader, information:"The EFI partition of " & diskName & " will be [un]mounted:" & return & return & infoText, icon:(resources & "AlertCautionIcon.icns"), buttons:{"Cancel", "Mount", "Unmount", "Change"}})
if button of reply is "Cancel" then error number -128
return {button:button of reply, answer:diskID}
end moreInfo
to showAlert given settings:arguments -- show a custom alert
set arguments to arguments & {title:"", message:"Alert", information:"", answer:missing value, icon:"", buttons:{"OK"}} -- a record is used for input parameters, unspecified keys will use default values
tell current application's NSAlert's alloc's init()
if (icon of arguments) as text is "Critical" then -- everything else is NSInformationalAlertStyle
set its alertStyle to current application's NSCriticalAlertStyle
else -- use the contents of an image file - informational icon will be used if no image or file (missing value)
set its icon to current application's NSImage's alloc's initByReferencingFile:((icon of arguments) as text)
end if
set its |window|'s title to (title of arguments) as text
set its messageText to (message of arguments) as text -- the bold text
set its informativeText to (information of arguments) as text -- the normal text
set buttonList to my (setButtons for it from (buttons of arguments))
if (answer of arguments) is not missing value then
set its |window|'s autorecalculatesKeyViewLoop to true
set accessory to my (makeComboAccessory for it)
set accessory's stringValue to answer of arguments
end if
activate me
set response to ((its runModal) as integer) - 999 -- get index - 1000 is rightmost button
end tell
if answer of arguments is not missing value then set answer of arguments to (accessory's stringValue) as text
return {button:item response of buttonList, answer:answer of arguments} -- returns a record: {button:(button title), answer:(text field value, or 'missing value' if not used)}
end showAlert
to setButtons for alert from buttons -- set buttons for the alert - filters for blanks and duplicates; returns a list of the button titles (left-to-right)
set {buttonList, theButton} to {{}, missing value}
repeat with aButton in reverse of (buttons as list) -- match dialog order
set aButton to aButton as text
if aButton is not in buttonList and aButton is not in {missing value, ""} then -- filter
set theButton to (alert's addButtonWithTitle:aButton)
set end of buttonList to aButton
end if
end repeat
if buttonList is {} then -- better have at least one
set theButton to alert's addButtonWithTitle:"OK"
set end of buttonList to "OK"
end if
set alert's |window|()'s initialFirstResponder to theButton -- the last (leftmost) one
return buttonList
end setButtons
to makeComboAccessory for alert -- make and return a comboBox accessory view for the alert
tell (current application's NSComboBox's alloc's initWithFrame:{{0, 0}, {288, 28}})
set its completes to true
set its hasVerticalScroller to true
set its placeholderString to "a disk identifier, for example disk0" -- arbitrary
repeat with anItem in identifiers -- populate the combo box with the disks with EFI partitions
set here to offset of "s" in (reverse of characters of anItem) as text
set anItem to text 1 thru -(here + 1) of anItem -- strip off partition
(its addItemWithObjectValue:anItem)
end repeat
set alert's accessoryView to it
return it
end tell
end makeComboAccessory
to checkID(diskID) -- check the disk identifier against the EFI partitions - returns the EFI partition, or missing value if not found
if diskID is not "" then repeat with anItem in identifiers
set anItem to anItem as text
set here to offset of "s" in (reverse of characters of anItem) as text -- partition index
if text 1 thru -(here + 1) of anItem is first word of diskID then return anItem
end repeat
return missing value
end checkID
to trimWhitespace(someText) -- trim whitespace characters from the beginning and end of a string
set someText to someText as text
if someText is "" then return ""
set whiteSpace to {space, tab, return, linefeed}
repeat until the first character of someText is not in whiteSpace
if (count someText) is 1 then return ""
set someText to text 2 thru -1 of someText
end repeat
repeat until the last character of someText is not in whiteSpace
if (count someText) is 1 then return ""
set someText to text 1 thru -2 of someText
end repeat
return someText
end trimWhitespace
to setup() -- set up properties and stuff
set {theDisks, identifiers} to {"", {}}
try
repeat with aPartition in paragraphs of (do shell script "diskutil list | grep 'EFI EFI' | grep -E -o 'disk[0-9]?[0-9]s[0-9]?[0-9]'") -- just EFI partitions named EFI
set aDisk to first paragraph of (do shell script "diskutil list " & aPartition)
if aDisk does not contain "disk image" then -- don't add disk images
set diskName to (do shell script "diskutil info " & text 1 thru -3 of aPartition & " | grep 'Media Name' | awk '{print substr($0,index($0,$5))}'")
if diskName is in {"", missing value} then
set diskName to ""
else
set diskName to "(" & diskName & ")"
end if
set theDisks to theDisks & tab & text 1 thru 11 of aDisk & space & diskName & return
set end of my identifiers to aPartition
end if
end repeat
if (count identifiers) < 1 then error "No EFI partitions were found."
return theDisks -- returns the disks found with EFI partitions (for the initial dialog)
on error errmess
log errmess
showAlert given settings:{title:"EFI [un]Mounter", message:return & errmess, icon:(resources & "AlertStopIcon.icns")}
error number -128
end try
end setup

How to save your desktop elements (icons, files,folder ) always on the same place with applescript

With the script we are going to create another script where will be store position of all the elements of the desktop, the created script will be compile and usable to put back in place all the elements previously protected.
/adesktopsave/deskico.txt it is the temporary file which will be of use to the compilation.
/adesktopsave/savedicoposition.scpt It is the script of saving that is compiled to be used with applescrit
All the names used here exist that just for the example. These names have no particular property.
It is just necessary to plan to create a folder before using this script. Here it is:
/adesktopsave
Something else, end of line (\n) after " try
"
also " end try
"
and & "}
")
Are very important to respect so that the text is usable.
tell application "Finder" to set theList to {name, desktop position} of items of desktop
try
do shell script "rm -f /adesktopsave/deskico.txt"
do shell script "echo tell application " & quoted form of (quote & "Finder" & quote) & return & " >>/adesktopsave/deskico.txt"
end try
set n to (count (first item of theList))
repeat with i from 1 to n
set inp to do shell script "echo " & quoted form of (item i of first item of theList)
set xy to (item i of second item of theList)
set AppleScript's text item delimiters to ","
set xyz to do shell script "echo " & xy
set wxyz to ("{" & xyz & "}
")
set ligne to "try
" & "set desktop position of item " & quoted form of (quote & inp & quote) & " of desktop to " & quoted form of (wxyz) & "end try
"
set ligne to do shell script "echo " & ligne & " >>/adesktopsave/deskico.txt"
end repeat
do shell script "echo " & "end tell" & return & " >>/adesktopsave/deskico.txt"
display dialog "Do you want to save your icons in their current location?" buttons {"Cancel", "Save"} default button 2 with title "Save the positions of icons"
if (button returned of result) is "Cancel" then
set n to do shell script "echo " & n
else
do shell script "osacompile -o " & "/adesktopsave/savedicoposition.scpt" & " /adesktopsave/deskico.txt"
end if
return n
We can lighten the script to its simplest expression. At the risk of having errors can be.
set ligne to ""
do shell script "mkdir -p /adesktopsave"
tell application "Finder" to set {names, positions} to {name, desktop position} of items of the desktop
set ligne to "tell application \"Finder\"
"
set n to (count names)
set AppleScript's text item delimiters to ","
repeat with i from 1 to n
set ligne to ligne & ("try
" & "set desktop position of item " & (quote & item i of names & quote) & " to {" & item i of positions & "}
end try
")
end repeat
set ligne to ligne & ("end tell" & return)
display dialog "Do you want to save your icons in their current location?" buttons {"Cancel", "Save"} default button 2 with title "Save the positions of icons"
if (button returned of result) is "Cancel" then
set n to do shell script "echo " & n
else
do shell script "osacompile -o " & "/adesktopsave/savedicoposition.scpt -e " & quoted form of ligne
end if
set AppleScript's text item delimiters to ""
tell application "Finder" to open POSIX file "/adesktopsave/savedicoposition.scpt"
return n

Detect battery percentage with applescript

How would I detect what my computer's battery percentage is at and set it to a variable using applescript? All answers to similar questions say to install additional software, but I would like to do this with purely applescript. Is this possible? I've also tried searching through the applescript library with no success.
on run
set theBattString to (do shell script "pmset -g batt")
-- the above will return something like...
-- Now drawing from 'Battery Power' -InternalBattery-0 82%; discharging; 4:06 remaining
end run
Now you can parse theBattString to get the information you'd like from it.
Another option...
on run
do shell script "ioreg -l | grep -i capacity | tr '\\n' ' | ' | awk '{printf(\"%.2f%%\\n\", $10/$5 * 100)}'"
-- will output...
-- 79.63%
end run
The applescript unsigned variable can be used like a signed FileMaker variable... the ** can be removed I tried it Bold it
set batteryPercent to do shell script "pmset -g batt "
tell application "FileMaker Pro.app"
tell table "Power Test Results"
tell record 1
set cell "Test percentage via AppleScript Global" to batteryPercent
end tell
end tell
end tell
Thank ThrowBackDewd for his answer.
I made something a bit strange but it works for me.
Here is the AppleScript
[EDIT]
Here a more efficient code thanks to user #user3439894.
set batteryPercent to word 6 of paragraph 2 of (do shell script "pmset -g batt")
if batteryPercent < 40 then
beep
repeat 3 times
say "Attention " & batteryPercent & "%" & " before shut down."
display notification "Attention " & batteryPercent & "%" & " of charge before shut down." sound name "Glass"
end repeat
end if
idle application
on idle
set batteryPercent to word 6 of paragraph 2 of (do shell script "pmset -g batt")
if batteryPercent < 40 then
repeat 3 times
beep
say "Attention " & batteryPercent & "%" & " of charge before shut down."
display notification "Attention " & batteryPercent & "%" & " of charge before shut down." sound name "Glass"
end repeat
end if
return 60
end idle
[First post]
set theBattString to (do shell script "pmset -g batt")
-- the above will return something like...
-- Now drawing from 'Battery Power' -InternalBattery-0 82%; discharging; 4:06 remaining
set batteryLevel to splitText(theBattString, space)
--set totalItembatLvl to length of batteryLevel
set remainingTime to item 9 of batteryLevel
if remainingTime < "2:40" then
display alert "low battery " & remainingTime & " before shut down."
--batteryLevel & " " & remainingTime
end if
on splitText(theText, theDelimiter)
set AppleScript's text item delimiters to theDelimiter
set theTextItems to every text item of theText
set AppleScript's text item delimiters to ""
return theTextItems
end splitText
on getPositionOfItemInList(theItem, theList)
repeat with a from 1 to count of theList
if item a of theList is theItem then return a
end repeat
return 0
end getPositionOfItemInList
You can add it in an idle statement and check every minute for your battery level.
Any suggestions or corrections will be appreciated.
Regards.

how to read text files in file made in applescript

How would i read the text the user defined in pass.txt
This is What I have so far to test it you must make a folder on your desktop called test
but I bet most of you could have figured that out
set choice to the button returned of (display dialog "Login or Signup" buttons {"Quit", "Signup", "Login"} default button "Login")
if choice is "Signup" then
set username to the text returned of (display dialog "Enter Desired Username" default answer "")
do shell script "mkdir $HOME/Desktop/test/" & username
do shell script "echo " & username & " > ~/desktop/test/" & username & "/username.txt"
set pass to the text returned of (display dialog "Enter Password" default answer "")
set input to pass
do shell script "echo " & pass & " > ~/desktop/test/" & username & "/pass.txt"
else if choice is "Login" then
set username to the text returned of (display dialog "Enter Username" default answer "")
set y to username
set z to "pass.txt"
set x to "/Desktop/test/" & y
words of {(read (POSIX file x) & "/pass.txt") as «class utf8»} contains pass -- true
set pass to the text returned of (display dialog "Enter Password" default answer "")
else
return 0
end if
The brackets are not set correctly. Try this:
read POSIX file (x & "/pass.txt")
or
do shell script "cat " & quoted form of (POSIX path of (path to desktop) & "test/" & username & "/pass.txt")
There are many other issues in the script anyway. Just a few tips, use...
-quoted form of pathes
-the -p option for mkdir
-the with hidden answer option for password entry

Resources