McUsr
July 24, 2012, 1:59am
#21
Hello!
I came by this document on the net, from 1997.
I wonder if you know about any more updated resource on the subject matter?
I see code where people address System Events with “syscve” or similiar, and also sending «event Pcap» I wonder, if this partuclar lore can be found somewhere, or is there just tid bits floating around?
You can hunt through the header files, or just look at code in Script Debugger showing raw syntax. But of themselves, they’re not particularly enlightening.
McUsr
July 24, 2012, 3:08am
#23
That is so true, about enlightening, and must I add interesting. But sometimes, there are gems to be found, like the trick by running a script to make something into a format that for example finder will take, with lists with keywords and specifiers that finder will understand, and accept. Or the trick by throwing an error to get read access to a datstructure, that are otherwise consealed, by reading the error string.
Sometimes, things can only be accomplished by a trick , and then it is good to know where to look for it!
And sometimes, you want sheer speed, not that it is neccessary at all times, but when the system is bogged down, then it helps, both to the robustness, and the responsetimes.
That is the only thing I can see as a liable excuse for using the more arcane language constructs.
By the way I figured out by some googling, that the alternative application id, was the applications creator type, that it can be used as an alternative for the bundle identifier
On my way I also learned that the bundle identifier of apps may vary with whether they are bought in the Appstore or not, and that holds for the creator type as well.
I found that part in http://forums.omnigroup.com/showthread.php?p=98911
McUsrII
November 20, 2013, 3:03pm
#24
Hello.
I have updated the script for Mavericks, TextWranglers path to twdiff has changed, I have also removed references to my “coreLibraryLoaderServer”, as with some new technology, and pretty much before that, it was obsolete. Lots of work to make it work, and it still does! But not worth the effort, in any sense.
The script still decompiles two applescripts, and puts it up into TextWrangler, so you’ll need TextWrangler for this one, and the command line tools installed.
P.S If you had the commandline tools installed before you installed Mavericks over your old operating system, then you may have to reinstall them. I had to at least. If this script doesn’t seem to work, then please visit a terminal window and execute the command which twdiff .
-- © McUsr 2010 and put in Public Domain see: macscripter.net/viewtopic.php?id=33758 (post #26) for reference and terms of use.
(*
Copyright © 2010 - 2015 McUsr: Fixed a bug in the classifyASfile() handler.
You may not post this as a work on your own somewhere, including paper.
*)
on run
tell application "Finder"
activate
set theSel to (get selection)
set selCount to count theSel
if selCount is 2 then
set {fileA, fileB} to {item 1 of theSel, item 2 of theSel}
else
if selCount is greater than 3 then my errMsg()
if (count its windows) is 1 or selCount is 0 then my errMsg()
-- only the desktop window or no items in the selection, -we don't handle folders - yet?
set fileA to item 1 of theSel
if class of fileA is not document file and class of fileA is not application file then my errMsg()
set fw1 to a reference to its Finder window 1
tell its Finder window 2 to activate
set theSel to (get selection) -- of Finder window 2
set selCount to count theSel
if selCount ≠1 then my errMsg()
set fileB to item 1 of theSel
if class of fileB is not document file and class of fileB is not application file then my errMsg()
tell fw1 to activate
if contents of fileB is equal to contents of fileA then my errMsg()
end if
set {mustDecompileFileA, mustDecompileFileB} to {my classifyASfile(fileA), my classifyASfile(fileB)}
-- there were something applescript a like so we will commence
set shortNm to name of fileA
set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "."}
set shortNm to text item 1 of shortNm
set AppleScript's text item delimiters to ""
set shortNm to shortNm as text
set theDir to do shell script "/usr/bin/mktemp -d -t " & quoted form of shortNm
set tempFn1 to quoted form of (theDir & "/" & my createPathDenotingFileNameWitoutExt((fileA as alias as text)))
set tempFn2 to quoted form of (theDir & "/" & my createPathDenotingFileNameWitoutExt((fileB as alias as text)))
if mustDecompileFileA then
my decompileAppleScriptTextForDiff((fileA as alias), tempFn1)
else
try
do shell script "cp " & quoted form of POSIX path of (fileA as alias) & " " & tempFn1
end try
end if
if mustDecompileFileB then
my decompileAppleScriptTextForDiff((fileB as alias), tempFn2)
else
try
do shell script "cp " & quoted form of POSIX path of (fileB as alias) & " " & tempFn2
end try
end if
end tell
-- make the differences show up in text wrangler!
try
set myres to (do shell script "/usr/local/bin/twdiff --ignore-spaces " & tempFn1 & " " & tempFn2)
tell (path to frontmost application as text)
display dialog "The files are alike!" with title "AppleScriptDiff" buttons {"Ok"} default button 1
end tell
on error e number n
tell application "TextWrangler"
activate
end tell
end try
end run
on classifyASfile(aFileRef)
tell application "Finder"
if file type of aFileRef is "osas" then return true
end tell
set aFileRef to aFileRef as alias
tell application id "sevs"
set ftype to type identifier of (get properties of item (aFileRef as text))
if ftype contains "com.apple.applescript.script" then
-- works for "com.apple.applescript.script" and "com.apple.applescript.script-bundle"
return true
else
return false
end if
end tell
end classifyASfile
on errMsg()
beep
tell (path to frontmost application as text)
display dialog "You need to select two and only two two different Apple Script files in the frontmost Finder Window or one file in each of the two frontmost Finder windows in order to run this script. If you are trying to get diffs of applets those need to have the original filepropeties as when the applet was saved in the editor in order for the script to run properly.
" with title "AppleScriptDiff" buttons {"Ok"} default button 1
end tell
error number -128
end errMsg
on decompileAppleScriptTextForDiff(fileAlias, qpxTempFileName) -- Thanks to oldmanegan
local theSourceText, qfPoxPath
set qfPoxPath to quoted form of POSIX path of (fileAlias)
try
fileAlias as alias
on error e number n
set bad to true
end try
try
beep
do shell script "/usr/bin/osadecompile " & qfPoxPath & "| /usr/bin/tr -d '\\000' >" & qpxTempFileName
on error e number n
tell application (path to frontmost application as text)
display dialog "AppleScriptDiff: decompileAppleScriptTextForDiff()" & e & " : " & n with title "AppleScriptDiff" buttons {"Ok"} default button 1
end tell
error number -128
end try
end decompileAppleScriptTextForDiff
on createPathDenotingFileNameWitoutExt(hfSfileNameAsText)
set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ":"}
-- set hfsFilenameAsText to {""} & text items 2 thru -1 of hfsFilenameAsText
-- Uses the line above instead of line under if you want to convert to unix alike filename.
set hfSfileNameAsText to text items of hfSfileNameAsText
set AppleScript's text item delimiters to "_"
set hfSfileNameAsText to hfSfileNameAsText as text
set AppleScript's text item delimiters to "."
set hfSfileNameAsText to text items 1 thru -2 of hfSfileNameAsText as text
set AppleScript's text item delimiters to tids
return hfSfileNameAsText
end createPathDenotingFileNameWitoutExt
McUsrII
November 26, 2013, 4:08pm
#25
Hello.
I removed a bug I had entered, in the handler that created a filename denoting the path of the original filename.
It is now fixed.
McUsrII
November 26, 2013, 4:14pm
#26
Hello.
This is a version that shows the differences between two AppleScript files with FileMerge. Maybe I should have coalesced the two into one script, but then you’d have to do more than simple executing the script.
I did the same to the Show Differences in two “normal” text files with TextWrangler ; added a script at the end that used FileMerge as well.
I feel more comfortable by using FileMerge, when the whole differences thing is for viewing purposes.
-- © McUsr 2013 and put in Public Domain see: macscripter.net/viewtopic.php?id=33758 (post #26) for reference and terms of use.
(*
Copyright © 2010 - 2015 McUsr: Fixed a bug in the classifyASfile() handler.
You may not post this as a work on your own somewhere, including paper.
*)
on run
tell application "Finder"
activate
set theSel to (get selection)
set selCount to count theSel
if selCount is 2 then
set {fileA, fileB} to {item 1 of theSel, item 2 of theSel}
else
if selCount is greater than 3 then my errMsg()
if (count its windows) is 1 or selCount is 0 then my errMsg()
-- only the desktop window or no items in the selection, -we don't handle folders - yet?
set fileA to item 1 of theSel
if class of fileA is not document file and class of fileA is not application file then my errMsg()
set fw1 to a reference to its Finder window 1
tell its Finder window 2 to activate
set theSel to (get selection) -- of Finder window 2
set selCount to count theSel
if selCount ≠1 then my errMsg()
set fileB to item 1 of theSel
if class of fileB is not document file and class of fileB is not application file then my errMsg()
tell fw1 to activate
if contents of fileB is equal to contents of fileA then my errMsg()
end if
set {mustDecompileFileA, mustDecompileFileB} to {my classifyASfile(fileA), my classifyASfile(fileB)}
-- there were something applescript a like so we will commence
set shortNm to name of fileA
set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "."}
set shortNm to text item 1 of shortNm
set AppleScript's text item delimiters to ""
set shortNm to shortNm as text
set theDir to do shell script "/usr/bin/mktemp -d -t " & quoted form of shortNm
set tempFn1 to quoted form of (theDir & "/" & my createPathDenotingFileNameWitoutExt((fileA as alias as text)))
set tempFn2 to quoted form of (theDir & "/" & my createPathDenotingFileNameWitoutExt((fileB as alias as text)))
if mustDecompileFileA then
my decompileAppleScriptTextForDiff((fileA as alias), tempFn1)
else
try
do shell script "cp " & quoted form of POSIX path of (fileA as alias) & " " & tempFn1
end try
end if
if mustDecompileFileB then
my decompileAppleScriptTextForDiff((fileB as alias), tempFn2)
else
try
do shell script "cp " & quoted form of POSIX path of (fileB as alias) & " " & tempFn2
end try
end if
end tell
try
do shell script "(/usr/bin/opendiff " & tempFn1 & " " & tempFn2 & " ) &> /dev/null &"
end try
end run
on classifyASfile(aFileRef)
tell application "Finder"
if file type of aFileRef is "osas" then return true
end tell
set aFileRef to aFileRef as alias
tell application id "sevs"
set ftype to type identifier of (get properties of item (aFileRef as text))
if ftype contains "com.apple.applescript.script" then
-- works for "com.apple.applescript.script" and "com.apple.applescript.script-bundle"
return true
else
return false
end if
end tell
end classifyASfile
on errMsg()
beep
tell (path to frontmost application as text)
display dialog "You need to select two and only two two different Apple Script files in the frontmost Finder Window or one file in each of the two frontmost Finder windows in order to run this script. If you are trying to get diffs of applets those need to have the original filepropeties as when the applet was saved in the editor in order for the script to run properly.
" with title "AppleScriptDiff" buttons {"Ok"} default button 1
end tell
error number -128
end errMsg
on decompileAppleScriptTextForDiff(fileAlias, qpxTempFileName) -- Thanks to oldmanegan
local theSourceText, qfPoxPath
set qfPoxPath to quoted form of POSIX path of (fileAlias)
try
fileAlias as alias
on error e number n
set bad to true
end try
try
beep
do shell script "/usr/bin/osadecompile " & qfPoxPath & "| /usr/bin/tr -d '\\000' >" & qpxTempFileName
on error e number n
tell application (path to frontmost application as text)
display dialog "AppleScriptDiff: decompileAppleScriptTextForDiff()" & e & " : " & n with title "AppleScriptDiff" buttons {"Ok"} default button 1
end tell
error number -128
end try
end decompileAppleScriptTextForDiff
on createPathDenotingFileNameWitoutExt(hfSfileNameAsText)
set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ":"}
-- set hfsFilenameAsText to {""} & text items 2 thru -1 of hfsFilenameAsText
-- Uses the line above instead of line under if you want to convert to unix alike filename.
set hfSfileNameAsText to text items of hfSfileNameAsText
set AppleScript's text item delimiters to "_"
set hfSfileNameAsText to hfSfileNameAsText as text
set AppleScript's text item delimiters to "."
set hfSfileNameAsText to text items 1 thru -2 of hfSfileNameAsText as text
set AppleScript's text item delimiters to tids
return hfSfileNameAsText
end createPathDenotingFileNameWitoutExt
Removed a bug in the Script in post #26 The bug wouldn’t kick in, until you tried to compare something different than a file with a filetype of “osas”, -it took five years before I did just that, and realized, there were a missing handler in there. The issue is fixed.
Hello.
I have updated the almost identical script that shows differences in TextWrangler as well (post #24 )
pjh
May 29, 2025, 2:42pm
#29
Made the above diff script work in a modern-OS-environment. Can use Apple’s FileMerge or BBEdit’s bbdiff.
-- © McUsr 2010 and put in Public Domain see: macscripter.net/viewtopic.php?id=33758 (post #26) for reference and terms of use.
(*
Copyright © 2010 - 2015 McUsr: Fixed a bug in the classifyASfile() handler.
You may not post this as a work on your own somewhere, including paper.
*)
(*
Changes 2025.05.29:
• updated code to work on more modern OSes and bundled file architectures
• script can use Apple's FileMerge or BBEdit's bbdiff by setting the useBBEdit property
• removed redundant and unused code
• handles (at least) 5 file types including .txt and .app
• improved error handling for non-AS-apps and read-only-scripts
• improved info quality of error messages
• shortened file paths while maintaining the file extensions to improve legibility in differ window title
*)
property useBBEdit : false -- use FileMerge; set to true to use BBEdit's bbdiff tool
property dialogTitle : missing value
on run
if useBBEdit then
set dialogTitle to "BBEditAppleScriptDiff"
else
set dialogTitle to "FileMergeAppleScriptDiff"
end if
tell application "Finder"
activate
set theSel to (get selection)
set selCount to count theSel
if selCount is 2 then
set {fileA, fileB} to {item 1 of theSel, item 2 of theSel}
else
if selCount is greater than 3 then my errMsg()
if (count its windows) is 1 or selCount is 0 then my errMsg()
-- only the desktop window or no items in the selection, -we don't handle folders - yet?
set fileA to item 1 of theSel
if class of fileA is not document file and class of fileA is not application file then my errMsg()
set fw1 to a reference to its Finder window 1
tell its Finder window 2 to activate
set theSel to (get selection) -- of Finder window 2
set selCount to count theSel
if selCount ≠ 1 then my errMsg()
set fileB to item 1 of theSel
if class of fileB is not document file and class of fileB is not application file then my errMsg()
tell fw1 to activate
if contents of fileB is equal to contents of fileA then my errMsg()
end if
end tell
-- use original file names instead of main.scpt in applets!
set shortNm to name of fileA
set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "."}
set shortNm to text item 1 of shortNm
set AppleScript's text item delimiters to ""
set shortNm to shortNm as text
set theDir to do shell script "/usr/bin/mktemp -d -t " & quoted form of shortNm
-- spaces and • added to somewhat improve legibility of the FileMerge diff window title
set tempFn1 to quoted form of (theDir & "/" & my createPathDenotingFileName((fileA as text)) & " •")
set tempFn2 to quoted form of (theDir & "/• " & my createPathDenotingFileName((fileB as text)))
-- fileA and fileB are now alias references, pointing at main.scpt in the case of AS applets
set {mustDecompileFileA, fileA} to my classifyASfile(fileA)
set {mustDecompileFileB, fileB} to my classifyASfile(fileB)
if mustDecompileFileA then
my decompileAppleScriptTextForDiff(fileA, tempFn1)
else
try
do shell script "cp " & quoted form of POSIX path of fileA & " " & tempFn1
end try
end if
if mustDecompileFileB then
my decompileAppleScriptTextForDiff(fileB, tempFn2)
else
try
do shell script "cp " & quoted form of POSIX path of fileB & " " & tempFn2
end try
end if
if useBBEdit then
try -- error handling seems no longer necessary? it looks as if bbdiff returns error 1 when differences are found (?); no man page available (?)
set myres to (do shell script "/usr/local/bin/bbdiff --ignore-spaces " & tempFn1 & " " & tempFn2)
if myres = "" then
tell application "SystemUIServer"
display dialog "The files are identical!" with title dialogTitle buttons {"Ok"} default button 1
end tell
end if
on error e number n
-- log e
-- log n
tell application "BBEdit" to activate
end try
else
try
do shell script "(/usr/bin/opendiff " & tempFn1 & " " & tempFn2 & " ) &> /dev/null &"
end try
end if
end run
on classifyASfile(aFileRef)
set aFileRef to (aFileRef as alias)
tell application "Finder" to set fileType to file type of aFileRef
if fileType is "osas" then
return {true, aFileRef}
else if fileType is in {"APPL"} then -- "BNDL" not necessary, handled by type identifier below
try
set aFileRef to alias ((aFileRef as text) & "Contents:Resources:Scripts:main.scpt")
on error e number n
-- log n -- -1728
-- log e -- "… kann nicht gelesen werden."
set errMsg to "Error: " & return & return & e & return & return & "This app does not seem to be an AppleScript app."
tell application "SystemUIServer"
display dialog errMsg with title dialogTitle buttons {"Ok"} default button 1
end tell
error number -128
end try
(*
tell application "Finder" to set fileType to file type of item aFileRef -- seems to always turn out as missing value
if fileType is "osas" then return {true, aFileRef}
*)
end if
tell application id "sevs"
set ftype to type identifier of aFileRef
if ftype begins with "com.apple.applescript.script" then
-- works for "com.apple.applescript.script" and "com.apple.applescript.script-bundle"
return {true, aFileRef}
else
return {false, aFileRef}
end if
end tell
end classifyASfile
on errMsg()
beep
tell application "SystemUIServer"
display dialog "You need to select two and only two two different Apple Script files in the frontmost Finder window or alternatively one file in each of the two frontmost Finder windows in order to use this script. Works with files of types '.applescript', '.txt', '.scpt', '.scptd', and '.app'" with title dialogTitle buttons {"Ok"} default button 1 with icon (path to resource "Unsupported.icns" in bundle ((path to library folder from system domain as text) & "CoreServices:CoreTypes.bundle") as alias)
end tell
error number -128
end errMsg
on decompileAppleScriptTextForDiff(fileAlias, qpxTempFileName) -- Thanks to oldmanegan
local qfPoxPath
set qfPoxPath to quoted form of POSIX path of (fileAlias)
try
--beep
set theCode to do shell script "/usr/bin/osadecompile " & qfPoxPath -- suppresses error if next step is piped directly
do shell script "echo " & quoted form of theCode & "| /usr/bin/tr -d '\\000' >" & qpxTempFileName -- delete octal NULL characters (\000)
on error e number n
-- log n -- n = 2 on error -1756
-- log e
if e contains "-1756" then
set errMsg to "Error: " & return & return & e & return & return & "Script was saved run only."
else
set errMsg to "Error: " & return & return & e & return & return
end if
tell application "SystemUIServer"
display dialog errMsg with title dialogTitle buttons {"Ok"} default button 1
end tell
error number -128
end try
end decompileAppleScriptTextForDiff
on createPathDenotingFileName(hfSfileNameAsText)
set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ":"}
set hfSfileNameAsText to text items of hfSfileNameAsText
-- remove last item if original hfSfileNameAsText has a trailing colon
if item -1 of hfSfileNameAsText is "" then set hfSfileNameAsText to items 1 thru -2 of hfSfileNameAsText
-- shorten long file path more or less sensibly to a maximum of 3 segments
if (count hfSfileNameAsText) > 3 then set hfSfileNameAsText to {item 1 of hfSfileNameAsText, "(…)", item -2 of hfSfileNameAsText, item -1 of hfSfileNameAsText}
set AppleScript's text item delimiters to "_"
set hfSfileNameAsText to hfSfileNameAsText as text
-- next lines commented out to maintain the file extensions, e. g. when comparing files with identical names but different extensions
--set AppleScript's text item delimiters to "."
--set hfSfileNameAsText to text items 1 thru -2 of hfSfileNameAsText as text
set AppleScript's text item delimiters to tids
return hfSfileNameAsText
end createPathDenotingFileName