The actual script’s byte code only has the raw Apple Event codes. That is a Finder enumeration, so your application would need to load Finder’s scripting terminology in order to look up what that raw code is. An alternative would be to use something like if statements to set the text equivalents.
The script editors load application terminology when you target the app with a tell statement in order to provide various editor features, but outside the editor your script/app does not - all it sees is the raw syntax (like Script Debugger’s view option).
I’m confused by what you’re saying. This IS taking place in a “Tell app “Finder”” clause. How would the script, as a standalone app, not load everything it needs from the Finder? I’ve never run in to this problem before.
And you say I need to load the Finder’s scripting terminology, what does that mean? How does one do that?
-- record disk format constants
set df1 to {label:"Mac OS Extended format", formatCode:«constant ****dfh+»}
set df2 to {label:"unknown format", formatCode:«constant ****df??»}
set df3 to {label:"NFS format", formatCode:«constant ****dfnf»}
-- list records
set diskFormats to {df1, df2, df3}
-- get lists of volume names and formats
tell application "Finder"
set TargetVolumeNames to name of disks
set TargetVolumeFormats to format of disks
end tell
-- cycle through volumes and possible disk formats
repeat with v from 1 to count of TargetVolumeNames -- each volume
set form to contents of item v of TargetVolumeFormats
repeat with f from 1 to count of diskFormats -- each possible format
if form is formatCode of item f of diskFormats then
set publish to label of item f of diskFormats
display dialog publish with title "Volume: " & (item v of TargetVolumeNames) giving up after 2
exit repeat
end if
end repeat
end repeat
But how would you load and look up the terminology directly?
Update
Maybe like this:
use scripting additions
run script "tell application \"Finder\" to delay 1/60"
tell application "Finder"
set df to (format of startup disk)
set hf to format of disk "home"
end tell
display dialog df as text giving up after 2
display dialog hf as text giving up after 2
-- Get the disk names directly from the Finder in case any contain commas.
tell application "Finder" to set diskNames to name of disks
-- Get the disk formats as a shell script text result and separate into a list.
set diskFormats to (do shell script "osascript -e 'tell app \"Finder\" to get format of disks'")
set diskFormats to split(diskFormats, ", ")
-- Pair and display the results.
repeat with i from 1 to (count diskNames)
display dialog (item i of diskFormats) with title ("Volume: " & item i of diskNames) giving up after 2
end repeat
on split(txt, delim)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to delim
set lst to txt's text items
set AppleScript's text item delimiters to astid
return lst
end split
Here is a solution with AppleScriptObjC for visible volumes:
use framework "Foundation"
use scripting additions
set theFileManager to current application's NSFileManager's defaultManager()
set theVolumes to theFileManager's mountedVolumeURLsIncludingResourceValuesForKeys:{} options:2 -- NSVolumeEnumerationSkipHiddenVolumes
set theVolumes to (theVolumes's valueForKey:"path")'s sortedArrayUsingSelector:"localizedCaseInsensitiveCompare:"
set theArray to current application's NSMutableArray's new()
repeat with aVolume in theVolumes
set theURL to (current application's NSURL's fileURLWithPath:aVolume)
set {hasResult, theFormat} to (theURL's getResourceValue:(reference) forKey:"NSURLVolumeLocalizedFormatDescriptionKey" |error|:(missing value))
set {hasResult, theName} to (theURL's getResourceValue:(reference) forKey:"NSURLVolumeLocalizedNameKey" |error|:(missing value))
(theArray's addObject:("" & theName & " = " & theFormat))
end repeat
(theArray's componentsJoinedByString:return) as string
As red_menace said, a script’s actual running code s a series of “Apple event” tokens. When you compile and save a script, it’s these tokens that are saved rather than the human-readable source code you’ve used. Conversely, when you open a script in Script Editor or Script Debugger, the editor automatically decompiles the tokens to display the human-readable form on the screen.
Scriptable applications have a “dictionary” of the keywords and tokens for their own specialist terminology. By specifying an application in the source code, you’re also telling the script editor where to look for the terminology information. When you run the script in the editor, the editor’s often able to return keywords as text because it’s decompiled the tokens and has the keyword text available. But when you run the script as an application, the editor’s not involved and you only get the event tokens.
Here is the system events adaptation. It has a local volume property.
I defaulted here to all disks. There is a commented out line to use as an example.
I put in some log commands so you can see what it’s doing when run from script editor.
Update: I should add that system events knows the format for the OS volumes (eg home, net) and thus returns ‘NFS Format’ instead of ‘unknown format’ as the finder does.
use scripting additions
-- record disk format constants
set df1 to {label:"Mac OS Extended format", formatCode:«constant ****dfh+»}
set df2 to {label:"NFS format", formatCode:«constant ****dfnf»}
set df3 to {label:"unknown format", formatCode:«constant ****df??»}
-- as list of records
set diskFormats to {df1, df2, df3}
tell application "System Events"
-- set volumeList to a reference to (disks whose startup is false and visible is false and local volume is true)
set volumeList to a reference to disks
set n to name of volumeList
log n -- name of every matching volume
set vf to format of volumeList
log vf -- format of every matching volume
end tell
repeat with v from 1 to count of n -- 1 to 2
repeat with f from 1 to count of diskFormats -- 1 to 3
log {contents of item v of vf, formatCode of item f of diskFormats} -- format test: actual to enumeration
if item v of vf is equal to formatCode of item f of diskFormats then
set publish to label of item f of diskFormats
display dialog publish with title "volume: " & item v of n giving up after 2
exit repeat
end if
end repeat
end repeat
This works well. I am sometimes leery of do shell script but I guess the slight delay here is immaterial.
Oddly, while your script works fine, I cannot run the ‘do shell script’ command in the terminal. osascript -e 'tell app \"Finder\" to get format of disks' returns an error:
"syntax error: Expected expression, property or key form, etc. but ¬
found unknown token. (-2741)"
It also failed when I split it into three separate commands.
And yet another option would be to use run script to do the whole thing, for example:
set testing to (run script "set theFormats to {}
tell application \"Finder\"
repeat with anItem in (get disks)
set end of theFormats to {diskName:(name of anItem), diskFormat:(format of anItem) as text}
end repeat
end tell
return theFormats") -- list of records
-- or --
tell application "Finder" to set targetVolumeName to name of startup disk
set testing to (run script "on run argv
tell application \"Finder\" to return (format of disk (first item of argv)) as text
end run" with parameters targetVolumeName) -- text value of enum
run script essentially does the same thing as osascript, in that they both run the script in a separate instance, although run script also compiles the result for you.
Guys I hate to sound like a broken record, but I’m still not understand what’s going on here.
I’ve tried some of your examples posted, and I can see how when you have a script look up the information in a “subscript” of some kind, it works. But when you do it natively, it does not work.
But why is that? What does the script-in-a-script do that running the script directly does not do?
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
-- Run your original script to gather disk information
set theFormats to {}
tell application "Finder"
repeat with anItem in (get disks)
set end of theFormats to {diskName:(name of anItem), diskFormat:(format of anItem) as text}
end repeat
end tell
-- Format the results as a string for saving to a text file
set resultString to "Disk Information Results:
"
repeat with aDisk in theFormats
set resultString to resultString & "Disk Name: " & (diskName of aDisk) & ", Format: " & (diskFormat of aDisk) & "
"
end repeat
-- Define the path to save the text file on the desktop
set desktopPath to (path to desktop as text) & "Disk Info Results.txt"
-- Create and write the results to the text file
try
set fileRef to open for access file desktopPath with write permission
write resultString to fileRef starting at 0
close access fileRef
display dialog "Disk information has been saved as disk_info_results.txt on your Desktop!" buttons {"OK"} default button "OK"
on error errMsg
display dialog "An error occurred: " & errMsg buttons {"OK"} default button "OK"
end try
The options I presented are just alternatives to using if statements or the other solutions presented. The main issue is to get the enumeration/constant as text, but when running a script application only the raw terminology (Apple Event) is used.
When using a tell statement in a script application these get converted to the text equivalent of the raw Apple Event, but when using run script, they are converted to their enumeration/constant text. osascript also converts to the enumeration/constant text, but is a little slower due to the do shell script overhead.
Running a script from the Terminal via osascript will also convert to the text equivalent of the raw Apple Event. However, running osascriptin a script from either the editor or Terminal will convert to the enumeration/constant text. A script must then be performing some Apple Event conversions for the run script and osascript (or do shell script) results, so I think this is just another of those things that make AppleScript weird.
I am still struggling with this. So even if the display dialog is within the “tell Finder” chunk, its still showing the raw code rather than the nice string, which I don’t get.
But ok so it doesn’t work. So how can I get the CODE out of it then? if i set a variable to the result of the format lookup, as string or as text, I’m still getting a full «constant ****dfh+» rather than just the format code itself.
And for that matter, not only do I want the text of the raw code, but is there a way I can force that, so even when this is run in the script editor, the results are still predictable.
3 lines after doing the format lookup, i’m doing flow control with the result. So I’d really like it to work as an application and within the script editor.
And yes I’m not using any of the sample code given because I’m really trying to keep my code simple and readable to me, potentially years from now when I revisit this and forget all about this whole mess.
Also of note, I thought the fix to this was going to be to put the display dialog box WITHIN the “Tell Finder” chunk, so it would still have the human readable version of the constant, not the raw code. But that didn’t work either.
All this said, even though I’m not getting how or why, I did implement one of the suggestions above after all and the script seems to be working as expected now.
set tdformat of TargetDisk to (run script "on run argv
tell application \"Finder\" to return (format of disk argv) as text
end run" with parameters (tdname of TargetDisk))
What red_menace and I have been trying to explain above is that scripts communicate with applications using Apple Event codes, not the human-readable terminology you see in Script Editor. When a script asks the Finder for, say, a disk’s format, the Finder returns its own Apple Event code for that format (e.g. «constant ****dfh+»), not the multi-word keyword you see (Mac OS Extended format) when you look at the result in Script Editor. Script Editor’s able to read the Finder’s scripting dictionary, decompile the event code, and show the equivalent source keyword on screen to make it easier for a scripter to see what’s going on. But the actual result’s still the event code, not the AppleScript text “Mac OS Extended format”, which is what you have to feed to display dialog if you want it to display that.