Helfer nach dem Umzug: die App repariert ihre Anmeldung selbst
macOS bindet einen privilegierten Dienst beim Anmelden an das Programm, das ihn angemeldet hat. Zieht das Programm um — aus „Downloads" nach „Programme", oder vom Bauverzeichnis in ein installiertes Bundle —, ist das ein anderes Bundle. Der alte Dienst läuft weiter und redet nicht mit dem neuen Programm. Von außen ist das die verwirrendste Kombination, die es gibt: der Zustand meldet „eingerichtet", und trotzdem kommt bei jedem Zugriff „Kommunikation mit der Hilfs-App nicht möglich". Ohne Reparatur bleibt nur, den Helfer von Hand zu entfernen und neu einzurichten — und darauf muss man erst kommen. Scheitert die Verbindung, während der Zustand „eingerichtet" meldet, meldet die App den Dienst jetzt einmal ab und wieder an. Einmal je Programmlauf: öfter wäre eine Schleife. Danach steht er auf „wartet auf Freigabe" — das Verschieben eines Programms mit Root-Dienst darf niemand still hinnehmen, auch diese App nicht. Dazu ein Fehler im DMG-Bau, der beim Nachbauen auffiel: war ein gleichnamiges Volume noch eingehängt, hängte macOS das neue als „Onyx 1" ein, während das AppleScript weiter „Onyx" einrichtete. Das Abbild kam ohne Fenstergestaltung heraus, ohne dass irgendetwas fehlschlug. Jetzt wird vorher abgehängt und der Einhängepunkt aus der Ausgabe gelesen statt geraten. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,9 @@ public final class FanControl: ChargeLimitReading {
|
|||||||
private var connection: NSXPCConnection?
|
private var connection: NSXPCConnection?
|
||||||
private var heartbeatTimer: Timer?
|
private var heartbeatTimer: Timer?
|
||||||
private var statusTimer: Timer?
|
private var statusTimer: Timer?
|
||||||
|
/// Ob die Registrierung in diesem Programmlauf schon einmal erneuert wurde.
|
||||||
|
/// Einmal ist Selbstheilung, immer wieder wäre eine Schleife.
|
||||||
|
private var hasRepairedRegistration = false
|
||||||
|
|
||||||
private var service: SMAppService {
|
private var service: SMAppService {
|
||||||
SMAppService.daemon(plistName: "com.scarriffleservices.onyx.helper.plist")
|
SMAppService.daemon(plistName: "com.scarriffleservices.onyx.helper.plist")
|
||||||
@@ -117,10 +120,41 @@ public final class FanControl: ChargeLimitReading {
|
|||||||
Task { @MainActor in
|
Task { @MainActor in
|
||||||
self?.lastError = error.localizedDescription
|
self?.lastError = error.localizedDescription
|
||||||
log.error("Helfer nicht erreichbar: \(error.localizedDescription, privacy: .public)")
|
log.error("Helfer nicht erreichbar: \(error.localizedDescription, privacy: .public)")
|
||||||
|
await self?.repairRegistration()
|
||||||
}
|
}
|
||||||
} as? OnyxHelperProtocol
|
} as? OnyxHelperProtocol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Meldet den Helfer ab und wieder an.
|
||||||
|
///
|
||||||
|
/// **Der Fall, für den das da ist: die App ist umgezogen.** Aus dem
|
||||||
|
/// Ordner „Downloads" nach „Programme", oder vom Bauverzeichnis in ein
|
||||||
|
/// installiertes Bundle. macOS bindet den privilegierten Dienst beim
|
||||||
|
/// Anmelden an das Programm, das ihn angemeldet hat — nach dem Umzug ist
|
||||||
|
/// das ein anderes Bundle. Der alte Dienst läuft weiter, redet aber nicht
|
||||||
|
/// mit dem neuen Programm.
|
||||||
|
///
|
||||||
|
/// Von außen ist das die verwirrendste Kombination, die es gibt: der
|
||||||
|
/// Zustand meldet „eingerichtet", und trotzdem kommt bei jedem Zugriff
|
||||||
|
/// „Kommunikation nicht möglich". Ohne diese Reparatur bleibt nur, den
|
||||||
|
/// Helfer von Hand zu entfernen und neu einzurichten — und darauf muss
|
||||||
|
/// man erst einmal kommen.
|
||||||
|
///
|
||||||
|
/// Danach steht der Dienst auf „wartet auf Freigabe": das Verschieben
|
||||||
|
/// eines Programms mit Root-Dienst darf niemand still hinnehmen, auch
|
||||||
|
/// diese App nicht.
|
||||||
|
private func repairRegistration() async {
|
||||||
|
guard !hasRepairedRegistration, installState == .installed else { return }
|
||||||
|
hasRepairedRegistration = true
|
||||||
|
log.notice("Helfer nicht erreichbar — Registrierung wird erneuert")
|
||||||
|
|
||||||
|
disconnect()
|
||||||
|
try? await service.unregister()
|
||||||
|
// launchd räumt den alten Dienst nicht im selben Atemzug ab.
|
||||||
|
try? await Task.sleep(for: .seconds(1))
|
||||||
|
install()
|
||||||
|
}
|
||||||
|
|
||||||
private func disconnect() {
|
private func disconnect() {
|
||||||
heartbeatTimer?.invalidate(); heartbeatTimer = nil
|
heartbeatTimer?.invalidate(); heartbeatTimer = nil
|
||||||
statusTimer?.invalidate(); statusTimer = nil
|
statusTimer?.invalidate(); statusTimer = nil
|
||||||
|
|||||||
@@ -33,15 +33,26 @@ make_pretty_dmg() {
|
|||||||
hdiutil create -volname "$volname" -srcfolder "$stage" -size 100m \
|
hdiutil create -volname "$volname" -srcfolder "$stage" -size 100m \
|
||||||
-fs HFS+ -format UDRW -ov "$temp" >/dev/null
|
-fs HFS+ -format UDRW -ov "$temp" >/dev/null
|
||||||
|
|
||||||
local mount="/Volumes/$volname"
|
# Ein gleichnamiges Volume vorher abhängen. Sonst hängt macOS das neue als
|
||||||
hdiutil attach "$temp" -nobrowse -quiet
|
# „Onyx 1" ein, das AppleScript richtet weiter „Onyx" ein — und das fertige
|
||||||
# Ohne kurze Pause findet das nächste Skript das Volume noch nicht.
|
# Abbild sieht aus wie vorher, ohne dass irgendetwas fehlschlägt.
|
||||||
|
while [ -d "/Volumes/$volname" ]; do
|
||||||
|
hdiutil detach "/Volumes/$volname" -force -quiet || break
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
# Den tatsächlichen Einhängepunkt aus der Ausgabe lesen statt ihn zu raten.
|
||||||
|
local mount
|
||||||
|
mount=$(hdiutil attach "$temp" -nobrowse -noverify \
|
||||||
|
| grep -o '/Volumes/.*' | tail -1)
|
||||||
|
[ -n "$mount" ] || { echo " (Abbild ließ sich nicht einhängen)"; return 1; }
|
||||||
|
local disk; disk="$(basename "$mount")"
|
||||||
sleep 2
|
sleep 2
|
||||||
|
|
||||||
echo "→ Fenster einrichten"
|
echo "→ Fenster einrichten"
|
||||||
osascript <<APPLESCRIPT >/dev/null || echo " (Finder nicht erreichbar — das Fenster bleibt schlicht)"
|
osascript <<APPLESCRIPT >/dev/null || echo " (Finder nicht erreichbar — das Fenster bleibt schlicht)"
|
||||||
tell application "Finder"
|
tell application "Finder"
|
||||||
tell disk "$volname"
|
tell disk "$disk"
|
||||||
open
|
open
|
||||||
set current view of container window to icon view
|
set current view of container window to icon view
|
||||||
set toolbar visible of container window to false
|
set toolbar visible of container window to false
|
||||||
|
|||||||
Reference in New Issue
Block a user