Icons von System-Apps ändern

Kommandos für den Echtlauf

Recovery-Mode booten, Safari öffnen und diese Webseite per Shortcut aufrufen:

cafe-megabyte.de/icons

Befehl kopieren und im Terminal ausführen:

csrutil disable; csrutil authenticated-root disable

Neustart, Skript ausführen und nochmals im Recovery-Mode booten.

Befehl kopieren und im Terminal ausführen:

csrutil enable; csrutil authenticated-root disable

Einleitung

Um Icons von Systemprogrammen zu ändern, muß ein gewisser Aufwand betrieben werden. Und diese Änderungen müssen bei jedem noch so kleinen Systemupdate wiederholt werden, da ein Update grundsätzlich alle Änderungen am Systemlaufwerk revidiert. Dieser Änderungsaufwand soll minimiert werden u.a. durch ein dynamisches Shell-Script (s.u.) und dem Shortlink cafe-megabyte.de/icons auf diese Webseite, um alle Arbeiten per Kopieren und Einfügen bzw. Drag / Drop erledigen zu können.

Grundsätzliches Vorgehen

  • SIP (System Integrity Protection) temporär und SSV (Signed System Volume) dauerhaft deaktivieren.
  • Systemlaufwerk schreibbar mounten.
  • Icon-Änderungen vornehmen.
  • Neuen Boot-Snapshot erstellen.
  • SIP (System Integrity Protection) wieder aktivieren und SSV (Signed System Volume) dabei deaktiviert lassen.

Automatisierung

Das Shellskript (s.u.) wird zusammen mit Icon-Dateien in einen Ordner gelegt. Wo der Ordner gespeichert wird, spielt keine Rolle. Eine Icon-Datei ist dabei eine leere Datei, auf der man im Finder ein Icon im Info-Fenster eingefügt hat.

Die Icon-Dateien müssen heißen wie Apps aus /System/Applications/ bzw. /System/Applications/Utilities/, z.B.:

  • Messages
  • Screen Sharing
  • Terminal
  • FindMy

Safari wird nicht unterstützt, da dieses über sog. Cryptex gesondert geschützt ist. Um das Safari-Icon zu ändern, lädt man sich am besten die Safari Technology Preview, deren Icon sich ganz normal im Finder ändern läßt und nutzt diese statt der Normalversion.

Vorbereitung und Testlauf

Sobald die anzupassenden Icons wie beschrieben in einem Ordner zusammen mit dem Skript vorbereitet wurden, kann das Skript ausgeführt werden, indem es in ein Terminalfenster gezogen wird. Beim Ausführen wird geprüft, ob das Signed System Volume (SSV) und die System Integrity Protection (SIP) deaktiviert wurden. Wenn nicht beide abgeschaltet wurden, läuft es im Testmodus. Dann werden keine Änderungen vorgenommen, aber es kann geprüft werden, ob die Namen der Icon-Dateien stimmen und die zugehörigen Programme gefunden werden.

Skript

Der Name der Skriptdatei (Icons setzen.sh) spielt keine Rolle, aber sie muß ausführbar sein:

chmod a+x "Icons setzen.sh"

Skript:

#!/bin/zsh

# Zweck
# -----
# Dieses Skript sollte zusammen mit Icon-Dateien in einem Ordner liegen. Es setzt alle diese Icons auf Systemprogramme.
# Das Skript muß nicht angepaßt werden, wenn neue Icon-Dateien hinzukommen oder welche entfallen.
# 
# Verwendung
# ----------
# Eine Icon-Datei ist dabei eine leere Datei, auf der man im Finder ein Icon im Info-Fenster eingefügt hat.
# Die Icon-Dateien müssen heißen wie Apps aus "/System/Applications" bzw. "/System/Applications/Utilities", z.B.:
# 	Messages
# 	Screen Sharing
#	Terminal
#	FindMy
#	...
#
# Testlauf
# --------
# Beim Ausführen prüft das Skript, ob das Signed System Volume (SSV) und SIP deaktiviert wurden. Wenn nicht, läuft es im Testmodus.
# Dabei werden keine Änderungen vorgenommen, aber es kann geprüft werden, ob die Namen der Icon-Dateien stimmen.
#
# Echtlauf
# --------
# Im Recovery-Mode starten und SIP und SSV deaktivieren:
#	csrutil disable; csrutil authenticated-root disable
# Neustarten und das Skript ausführen. Es endet mit dem Ausschalten-Dialog.
# Im Recovery-Modus SIP wieder einschalten:
#	csrutil enable; csrutil authenticated-root disable
# Neustart.


# Icon setzen
# Aufrufbsp.: set_icon "Screen Sharing"
set_icon() {

	# Parameter übernehmen
	local APP="$1"
	
	# Pfad zum Icon
	local ICONFILE="$WORKINGDIR/$APP"
	
	# Pfad zum App ermitteln
	if [ -e "$ROOTDIR/System/Applications/$APP.app" ]; then
		APP_PATH="$ROOTDIR/System/Applications/$APP.app"
	elif [ -e "$ROOTDIR/System/Applications/Utilities/$APP.app" ]; then
		APP_PATH="$ROOTDIR/System/Applications/Utilities/$APP.app"
	else
		echo "FEHLER - App nicht gefunden: $APP"
		exit 1
	fi
	printf "Setze Icon für $APP_PATH "

	# Echtlauf
	if [ ! "$STATUS" = "" ]; then

		# Icon extrahieren
		# Pipe sollte bei Rez und DeRez gehen, geht aber nicht, daher per Tempfile
		local TEMP_DEREZ=`mktemp /tmp/DeRez.XXX` || exit 1
		DeRez "$ICONFILE" -only icns > $TEMP_DEREZ
	
		# Extrahiertes Icon aufs App übertragen
		sudo Rez $TEMP_DEREZ -append -o "$APP_PATH/$FOLDERICONFILE"
		sudo chflags hidden "$APP_PATH/$FOLDERICONFILE"
		sudo SetFile -a C "$APP_PATH"
		echo ".....OK"
	
		# Extrahiertes Icon löschen
		rm $TEMP_DEREZ 

	# Testlauf
	else
		echo ".....Testlauf"
	fi
}

# Variablendeklaration erzwingen
set -u

# Bei Fehlern Skript abbrechen
set -e

# Name der Icon-Datei von Ordnern festlegen
FOLDERICONFILE="Icon$(printf '\r')"		# Wegen diesem Zeilenumbruch will es mit #!/bin/sh nicht klappen. :-(

# Können wir schreibbar mounten?
STATUS=`csrutil status | grep disabled` || true

if [ ! "$STATUS" = "" ]; then
	STATUS=`csrutil authenticated-root status | grep disabled` || true
fi

if [ "$STATUS" = "" ]; then	
	echo "SIP und SSV müssen im Recovery-Mode deaktiviert werden."
	echo "!!!!! TESTLAUF - Es werden KEINE ÄNDERUNGEN durchgeführt !!!!!"
fi

# Ggf. müssen die Command Line Tools installiert werden
if [ ! "$STATUS" = "" ]; then
	if [ ! -e /Library/Developer/CommandLineTools/usr/bin/Rez ]; then
		xcode-select --install
		echo "Command Line Tools installieren (siehe Popup)"
		echo "Taste drücken, um fortzufahren, wenn die Installation abgeschlossen ist."
		read -k1 -s
		if [ ! -e /Library/Developer/CommandLineTools/usr/bin/Rez ]; then
			echo "FEHLER: Command Line Tools nicht installiert."
			exit 1
		fi
	fi
fi

# sudo-Rechte vorab einholen, falls erforderlich
if [ ! "$STATUS" = "" ]; then
	if ! sudo --validate --non-interactive > /dev/null 2>&1; then
		printf "Admininistratorrechte erforderlich. "
		sudo --validate || exit 1
		echo
	fi
fi

# Bootlaufwerk ermitteln
BOOTDEVICE=`bless --info --getBoot`
echo "Systemlaufwerk: $BOOTDEVICE"

# Systemlaufwerk schreibbar mounten
if [ ! "$STATUS" = "" ]; then
	ROOTDIR="/Volumes/SCHREIBBAR"
	sudo mkdir -p $ROOTDIR
	sudo mount -o nobrowse -t apfs $BOOTDEVICE $ROOTDIR || true
	echo "Systemlaufwerk schreibbar gemountet."
else
	ROOTDIR=""		# für Testlauf
fi

# Wir erwarten, daß die Icons im selben Ordner liegen wie dieses Skript.
# Wir wechseln nun in diesen Ordner.
WORKINGDIR=`dirname "${0}"`
cd "$WORKINGDIR"
echo "Ins Icon-Verzeichnis gewechselt: $WORKINGDIR"

# Name des eigenen Skripts
SCRIPTNAME=`basename "${0}"`

# Schleife über alle Icons (= alle Dateien im aktuellen Verzeichnis)
echo
for ICON in *
do
	# Das Skript selbst und ein Custom-Icon des eigenen Ordners dabei überspringen
	if [ ! "$ICON" = "$SCRIPTNAME"     ] &&
	   [ ! "$ICON" = "$FOLDERICONFILE" ]
	then
		set_icon "$ICON" || exit 1
	fi
done
echo

# Fertig
if [ "$STATUS" = "" ]; then
	echo "Testlauf erfolgreich beendet"
else
	# Neuen Snapshot zum Booten erstellen
	if [[ $(uname -p) == 'arm' ]]; then
		sudo bless --mount $ROOTDIR/System/Library/CoreServices --create-snapshot
	else
		sudo bless --mount $ROOTDIR/System/Library/CoreServices --create-snapshot --bootefi
	fi

	
	
	echo "Neuer Snapshot zum Booten wurde erstellt."
	echo "Der Mac sollte jetzt im Recovery-Mode gestartet werden, um SIP wieder zu aktivieren. Siehe hierzu:"
	echo
	echo "\t cafe-megabyte.de/icons"
	
	# Ausschalten anbieten
	osascript -e 'tell app "loginwindow" to «event aevtrsdn»'
fi
echo