Hello
I know that I may ask the Finder to unlock a locked file with :
tell application "Finder"
set locked of item hfsPath to false -- Déverrouille le fichier/dossier
end tell
But as I continue to do my best to get rid of the Finder, I’m wondering if this may be done without using the Finder.
I looked in Xcode but it seems that the locked status isn’t reachable thru ASObjC.
Am I wrong ?
Yvan KOENIG running El Capitan 10.11.6 in French (VALLAURIS, France) vendredi 16 septembre 2016 12:47:48
Got it.
I must trigger NSURLIsUserImmutableKey.
use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
on unlockThat:HfsPath
set theURL to current application's class "NSURL"'s fileURLWithPath:(POSIX path of HfsPath)
set {theResult, theError} to theURL's setResourceValue:(false) forKey:(current application's NSURLIsUserImmutableKey) |error|:(reference)
end unlockThat:
set aFile to choose file "Please, select a locked one !"
tell application "Finder"
set lockedBefore to locked of aFile
end tell
my unlockThat:aFile
tell application "Finder"
set lockedAfter to locked of aFile
end tell
{lockedBefore, lockedAfter}
Yvan KOENIG running El Capitan 10.11.6 in French (VALLAURIS, France) vendredi 16 septembre 2016 14:46:00
Here is an easier way using do shell script
This will unlock the file
do shell script "chflags nouchg " & POSIX path of hfsPath
This will lock the file
do shell script "chflags uchg " & POSIX path of hfsPath
It might be easier in the sense of less typing (although it really needs a quoted form of in there), but it’s a heck of lot slower to run.
I put these two scripts in Script Geek to compare:
set aFile to alias "Macintosh HD:Users:shane:Desktop:Screen Shot 2016-09-17 at 2.18.36 PM.png"
do shell script "chflags uchg " & quoted form of POSIX path of aFile
do shell script "chflags nouchg " & quoted form of POSIX path of aFile
use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
on unlockThat:HfsPath
set theURL to current application's class "NSURL"'s fileURLWithPath:(POSIX path of HfsPath)
set {theResult, theError} to theURL's setResourceValue:(false) forKey:(current application's NSURLIsUserImmutableKey) |error|:(reference)
end unlockThat:
on lockThat:HfsPath
set theURL to current application's class "NSURL"'s fileURLWithPath:(POSIX path of HfsPath)
set {theResult, theError} to theURL's setResourceValue:(true) forKey:(current application's NSURLIsUserImmutableKey) |error|:(reference)
end lockThat:
set aFile to alias "Macintosh HD:Users:shane:Desktop:Screen Shot 2016-09-17 at 2.18.36 PM.png"
my unlockThat:aFile
my lockThat:aFile
When I set them to be run 100 times, the shell script version takes on average more than 70 times as long.
In fact, when I compare the shell script version with the Finder:
set aFile to alias "Macintosh HD:Users:shane:Desktop:Screen Shot 2016-09-17 at 2.18.36 PM.png"
tell application "Finder"
set locked of aFile to true
set locked of aFile to false
end tell
the Finder is nearly 10 times faster.
Speed isn’t everything, but if something’s that much slower than the Finder, it’s not a good look 
FYI, if you’re not going to check the result or do anything with the error, it’s a fraction simpler just to use:
theURL's setResourceValue:(false) forKey:(current application's NSURLIsUserImmutableKey) |error|:(missing value)
Thanks Shane.
I will not try to spare the time required to send the three values to the script.
At this time I don’t use them but one never knows.
Yvan KOENIG running El Capitan 10.11.6 in French (VALLAURIS, France) samedi 17 septembre 2016 09:40:34
There’s no need to pass them. If you think there could be an error, you could use this:
on unlockThat:HfsPath
set theURL to current application's class "NSURL"'s fileURLWithPath:(POSIX path of HfsPath)
set {theResult, theError} to theURL's setResourceValue:(false) forKey:(current application's NSURLIsUserImmutableKey) |error|:(reference)
if not theResult as boolean then
error (theError's |localizedDescription|() as text)
end if
end unlockThat:
Oops
It seems that my wording was wrong.
The original instruction was :
set {theResult, theError} to theURL's setResourceValue:(false) forKey:(current application's NSURLIsUserImmutableKey) |error|:(reference)
Your proposal was :
theURL's setResourceValue:(false) forKey:(current application's NSURLIsUserImmutableKey) |error|:(missing value)
I wanted to say that I had no need to grab the values « set {theResult, theError} to »
I don’t know why I wrote about three values when they are only true.
But the worse thing is that I missed that the last parameter used in the instruction changed from (reference) to (missing value) which is why « set {theResult, theError} to » become unneeded
.
Yvan KOENIG running El Capitan 10.11.6 in French (VALLAURIS, France) samedi 17 septembre 2016 15:41:13