list 32 bits applications

Hello

I built a GUI scripting code building a list of 32 bits applications installed on a machine but it’s awfully slow.

Is there a way to do that without GUI scripting ?

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) dimanche 7 avril 2019 19:06:57

Gathering application data takes a lot of time, either in System Information.app or in the shell.

Compare

do shell script "system_profiler SPApplicationsDataType"

Thanks Stefan.
It’s exactly what I wanted.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 8 avril 2019 09:11:35

Oops.
It 's not exactly what I needed.

I use my iMac with an internal disk “Macintosh HD” but I boot from an external SSD.

The script return the applications available on the boot volume but doesn’t list those available on “Macintosh HD” disk.

I will have to run it after booting from “Macintosh HD”.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 8 avril 2019 11:46:57

It seems that I was not really awake. The script returned the apps from both volumes.

It is better to make a list of 32-bit applications 1 time and have it on hand:



set SaveLocation to (choose file name with prompt "Save As File" default name "Non 64-bit App's List" default location path to desktop) as text

if SaveLocation does not end with ".txt" then set SaveLocation to SaveLocation & ".txt"

do shell script "system_profiler SPApplicationsDataType -timeout 0 | grep -B 6 -A 2 \"(Intel): No\" >" & space & quoted form of (POSIX path of SaveLocation)

Thanks.

In fact starting from Stefan’s message I wrote:

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

script o
	property Intel64 : {}
	property Intel32 : {}
end script

Germaine()

on Germaine()
	
	set startDate to current application's NSDate's |date|()
	
	set p2d to path to desktop as text
	--set theDataTypes to do shell script "system_profiler -listDataTypes"
	
	set fullReport to do shell script "system_profiler SPApplicationsDataType"
	
	set theDescriptors to items 2 thru -1 of my decoupe(fullReport, " Version:") # Don't remove the leading space because fullReport may contain "BuildVersion:"
	repeat with i from 1 to count theDescriptors
		set aDescriptor to theDescriptors's item i
		set {bof, theEnd} to my decoupe(aDescriptor, "Location: ")
		set thePath to first paragraph of theEnd
		if aDescriptor contains "64-Bit (Intel): Yes" then
			copy thePath to end of o's Intel64
		else if aDescriptor contains "64-Bit (Intel): No" then
			copy thePath to end of o's Intel32
		end if
	end repeat
	set timeDiff to startDate's timeIntervalSinceNow()
	
	my writeto(p2d & "Intel64.txt", my recolle(o's Intel64, linefeed), «class utf8», false)
	my writeto(p2d & "Intel32.txt", my recolle(o's Intel32, linefeed), «class utf8», false)
	display dialog "That took " & (-timeDiff as real) & " seconds." buttons {"Yes"}
end Germaine

#=====
(*
Handler borrowed to Regulus6633 - http://macscripter.net/viewtopic.php?id=36861
*)
on writeto(targetFile, theData, dataType, apendData)
	-- targetFile is the path to the file you want to write
	-- theData is the data you want in the file.
	-- dataType is the data type of theData and it can be text, list, record etc.
	-- apendData is true to append theData to the end of the current contents of the file or false to overwrite it
	try
		set targetFile to targetFile as «class furl»
		set openFile to open for access targetFile with write permission
		if not apendData then set eof of openFile to 0
		write theData to openFile starting at eof as dataType
		close access openFile
		return true
	on error
		try
			close access targetFile
		end try
		return false
	end try
end writeto

#=====

on decoupe(t, d)
	local oTIDs, l
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
	set l to text items of t
	set AppleScript's text item delimiters to oTIDs
	return l
end decoupe

#=====

on recolle(l, d)
	local oTIDs, t
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
	set t to l as text
	set AppleScript's text item delimiters to oTIDs
	return t
end recolle

#=====

After 32 seconds got a list of 371 32bits files and a list of 1282 64bits ones.
Then I ran

use AppleScript version "2.3.1"
use scripting additions
use framework "Foundation"

on setTags:tagList forPath:posixPath
	set thisURL to current application's |NSURL|'s fileURLWithPath:posixPath
	set {theResult, theError} to thisURL's setResourceValue:tagList forKey:(current application's NSURLTagNamesKey) |error|:(reference)
	if theResult as boolean is false then error (theError's |localizedDescription|() as text)
end setTags:forPath:

set startDate to current application's NSDate's |date|()
set p2d to (path to desktop as text)
set intel32 to p2d & "Intel32.txt"
set theLog to p2d & "the log.txt"
tell application "System Events"
	if exists disk item theLog then delete disk item theLog
end tell
set thePaths to paragraphs of (read (intel32 as «class furl») as «class utf8»)


repeat with aPath in thePaths
	
	try
		(my setTags:{"is 32bits"} forPath:(contents of aPath))
	on error errMsg
		my writeto(theLog, errMsg & tab & aPath & linefeed, «class utf8», true)
	end try
end repeat
set timeDiff to startDate's timeIntervalSinceNow()
display dialog "That took " & (-timeDiff as real) & " seconds." buttons {"Yes"}

#=====

(*
Handler borrowed to Regulus6633 - http://macscripter.net/viewtopic.php?id=36861
*)
on writeto(targetFile, theData, dataType, apendData)
	-- targetFile is the path to the file you want to write
	-- theData is the data you want in the file.
	-- dataType is the data type of theData and it can be text, list, record etc.
	-- apendData is true to append theData to the end of the current contents of the file or false to overwrite it
	try
		set targetFile to targetFile as «class furl»
		set openFile to open for access targetFile with write permission
		if not apendData then set eof of openFile to 0
		write theData to openFile starting at eof as dataType
		close access openFile
		return true
	on error
		try
			close access targetFile
		end try
		return false
	end try
end writeto

#=====

which required 0,75 second to tag the 32 bits files with “is 32bits” and issued a log file listing the 115 files which didn’t allow the tag to be applied because the hosting folders are protected (OSStatus erreur -5000).

As many 32 bits files were scripts saved years ago I re-saved them and now there are only 234 remaining 32 bits files (a lot of scripts will be re-saved later).

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 8 avril 2019 17:46:25

I decided to look again if I have any 32-bit applications. And I found that the above solutions do not work on Catalina. Due to this, and since @Yvan Koenig loves long scripts and I like short ones, I rewrote the script to a working one. Here it is:


set Intel32 to {}
set fullReport to do shell script "system_profiler SPApplicationsDataType"

set ATID to AppleScript's text item delimiters
set AppleScript's text item delimiters to " Version:"
set theDescriptors to text items 2 thru -1 of fullReport
set AppleScript's text item delimiters to "Location: "
repeat with aDescriptor in theDescriptors
	set aDescriptor to contents of aDescriptor
	set {bof, theEnd} to text items of aDescriptor
	if (aDescriptor contains "Kind: 32-Bit") or (aDescriptor contains "64-Bit (Intel): No") then ¬
		set end of Intel32 to name of application (paragraph 1 of theEnd)
end repeat
set AppleScript's text item delimiters to ATID

return Intel32