„defaults write“ statt „tell application 'System Preferences‘ …“ – wie aktivieren?

uhlhorn

Aktives Mitglied
Thread Starter
Dabei seit
24.05.2005
Beiträge
2.474
Reaktionspunkte
129
Ich hätte da mal eine Frage (weiter unten):

Ich kann Preferences-Einstellungen per AppleScript auf zweierlei Weise ändern: Entweder dass ich die Systempreferences fern steuere mit

Code:
tell application "System Preferences“
…
end tell

oder dass ich Terminal-Befehle erzeuge mit

Code:
do shell script "defaults write …“

Wenn ich nun die Werte mit default write … ändere, und die Systemeinstellungen neu öffne, sind sie geändert. Aber sie kommen noch nicht zur Anwendung.

Wenn ich per Maus die Einstellungen in den Systemeinstellungen ändere, kommen sie sofort zur Anwendung und werden auch in der entsprechenden plist geändert.

Nun meine Frage:
Wie kann ich erreichen, dass die geänderte plist, welche ich mit default write … geändert habe, aktiviert wird? Gibt es dafür einen Befehl?

Ich habe folgendes Programm was nicht funktioniert (ich habe übrigens eine deutsche Sprachsynthese installiert):

Code:
SchalteMausScrollen(1) -- 1 schaltet Mausscrollen aus, 0 schaltet es ein

on SchalteMausScrollen(Zustand)
	if Zustand is 1 then
		say "Mausscrollen ausschalten"
		do shell script "defaults write com.apple.driver.AppleBluetoothMultitouch.mouse MouseHorizontalScroll -bool NO"
		do shell script "defaults write com.apple.driver.AppleBluetoothMultitouch.mouse MouseVerticalScroll -bool NO"
	else
		say "Mausscrollen einschalten"
		do shell script "defaults write com.apple.driver.AppleBluetoothMultitouch.mouse MouseVerticalScroll -bool YES"
		do shell script "defaults write com.apple.driver.AppleBluetoothMultitouch.mouse MouseHorizontalScroll -bool YES"
		
	end if
end SchalteMausScrollen

Wenn ich es konventionell schreibe, dann funktioniert es. Aber es startet dann immer unnötigerweise die Systemeinstellungen. Hier ein funktionierendes Script:

Code:
SchalteMausScrollen(1) -- 1 schaltet Mausscrollen aus, 0 schaltet es ein

on SchalteMausScrollen(Zustand)
	tell application "System Preferences"
		activate
		set current pane to pane "Maus"
	end tell
	
	tell application "System Events"
		tell application process "System Preferences"
			--get entire contents of window "Maus"
			
			if Zustand is 1 then
				say "Mausscrollen ausschalten"
				--say "magic mouse scrolling off,"
			else
				say "Mausscrollen einschalten"
				--say "magic mouse scrolling on,"
			end if
			
			try
				repeat until value of checkbox "Scrollen" of group 1 of window "Maus" of application process "System Preferences" of application "System Events" is not Zustand
					click checkbox "Scrollen" of group 1 of window "Maus" of application process "System Preferences" of application "System Events"
				end repeat
			end try
			
			try
				repeat until value of checkbox "Bildschirmzoom" of group 1 of window "Maus" of application process "System Preferences" of application "System Events" is not Zustand
					click checkbox "Bildschirmzoom" of group 1 of window "Maus" of application process "System Preferences" of application "System Events"
					delay 1
				end repeat
			end try
			
			
			
		end tell
	end tell
	
end SchalteMausScrollen
 
Wie kann ich erreichen, dass die geänderte plist, welche ich mit default write … geändert habe, aktiviert wird? Gibt es dafür einen Befehl?

Ich fürchte, nein. In der Dokumentation zum Kommandozeilen-Tool defaults steht:
Note: Since applications do access the defaults system while they're running, you shouldn't modify the defaults of a running application. If you change a default in a domain that belongs to a running application, the application won't see the change and might even overwrite the default.

Man muss also den Prozess beenden, der mit der MagicMouse arbeitet, dann die Plist ändern und den Prozess neu starten, damit er die Plist neu einlesen muss... Ich habe aber keine Ahnung, welcher Prozess das ist und finde auch bei El Goog keine Antwort.
 
Ja, aber Apple kann es doch auch. Wenn man etwas in den Preferences einstellt wird es sofort übernommen. Der Mechanismus dafür ist in OS X also vorhanden. Die Frage ist nur: Wie kann ich das nutzen?
 
Nein nein, das interpretierst Du falsch.

Du schreibst auf ein Zettel "1" und gibst ihn mir.
Ich schreibe auf den Zettel "0". Woher solltest Du das wissen?
Du kannst es erst wissen, wenn Du den Zettel wieder bekommst.

Das schalten in der GUI selbst ändert zu einem die Parameter der Instanzen selbst und schreibt den aktuellen Zustand in der Plist weg.
Wenn Du da etwas änderst, dann können die Instanzen das nicht wissen.

Viele Grüße
 
Ja, eben! Wenn ich in den Preferences etwas ändere, wird der Prozess benachrichtigt, dass sich die Einstellungen geändert haben. Der betroffene Prozess lädt die Einstellungen neu und ändert sein Verhalten danach.

Eben um diese Kommunikation mit den Prozessen geht es mir ja. Wie kann ich sie nutzen? Wie kann ich dem Prozess mitteilen, dass sich Einstellungen geändert haben und er sie neu einlesen soll?
 
Ich denke das liegt daran, daß Cocoa-Programme wie z.B. die Systemeinstellungen in der Lage sind, diese Nachrichten mit einer NSNotification weiterzugeben und so die neuen Einstellungen sofort aktivieren können. Mit dem Terminal ist das meines wissens nicht möglich und deshalb müssen die Prozesse neugestartet werden, damit die neuen Werte eingelesen werden.

Ciao
Farid
 
Oder gehe das Problem vom anderen Ende an:
Führe dein Shellskript aus - dann trenne und verbinde die Magic Mouse (Bzw: Maus aus an)

Eventuell ginge auch: Bluetooth aus - an.
(Zumindest dafür gäbe es ein Command-Line Tool (namens blueutil), welches du in deinem Skript benutzen könntest)

Gruß
 
Ich mache eine ganze Reihe von Änderungen in den Preferences per Script:

• iChat trennen
• Diskimage mounten
• Funktionstasten auf Standard stellen
• Mausscrollen abschalten
• Programm starten
• Auf Beendigung des Programms warten
… und dann alles wieder zurück.

Und dann soll ich die USB-Tastatur abmelden?!? Und wie mache ich das mit Time Machine?

Nein, wenn es kein Befehl gibt um den Prozess anzustoßen und ihm mitzuteilen, dass neue Preferences vorliegen, dann lasse ich es lieber. :)
Ich hatte gehofft, dass es ein Terminal-Befehl gibt um die Einstellungen zu aktivieren. Aber das scheint ja nicht der Fall zu sein (oder es kennt ihn hier niemand).

Trotzdem danke.
 
Der betroffene Prozess lädt die Einstellungen neu und ändert sein Verhalten danach.
Nein, das Verhalten ist eben so nicht.

Einfaches Beispiel:
Ich habe ein Programm mit einer CheckBox "Ja/Nein".
Dann gibt es im Programm eine Variable dafür die, auf "Ja" steht. Jetzt änderst Du die Plist und setzt den Wert auf "Nein".
Dann hast Du damit nicht den Wert der Variable geändert.
Wenn jetzt die CheckBox auf "Nein" geklickt wird, dann wird die interne Variable geändert und der Zustand wird irgendwann mal zur Plist gesichert.

Warum sollte ein Programm seine Werte zur Plist sichern und dann wieder einlesen?
Das würde unnötig Kommunikation verursachen.

Wenn ich ein Programm auf habe, Werte ändere und das Programm nicht ordnungsgemäß schließe, dann sind die Werte im Regelfall auch verloren.
Ist auch klar, da die Werte nicht mehr gesichert werden konnten.

Plists werden im Regelfall bei Programmstart oder bei Erstellung einer Instanz ausgelesen.

Viele Grüße
 
Wenn ich aber in den System Preferences die Einstellungen der Maus ändere, dann ändere ich nicht die Variablen des „eigenen“ Programms, sondern die des „Mausprogramms“. Also muss doch die System Preferences die Werte irgendwie zu maus bekommen, oder?
 
Und dann soll ich die USB-Tastatur abmelden?!? Und wie mache ich das mit Time Machine?
Du hast eine sehr eigene Art von Ironie.

Oder aber du meinst das ernst und liest die Beiträge hier nicht richtig... :rolleyes:

Die Antwort zu deiner letzten Frage steht in #6.
Hier mal eine Prise Halbwissen meinerseits:
System Preferences - als Cocoa Programm - nutzt die beschriebenen Notifications, um Änderungen an das "Mausprogramm" weiterzugeben.
Dein "Mausprogramm" ist tatsächlich eine Art Programm, allerdings eines, welches dir eventuell unter dem Begriff "Treiber" eine Vorstellung von seiner Funktion geben könnte.
Es ist eine Kernel Extension. Und zwar nicht eine, die bei Bedarf geladen wird, sondern beim Start. Deswegen liegt sie auch im Ordner System. OSX als Haus vorgestellt, sitzen sie gleich über dem Fundament, dem Kernel. Man kann sie nicht einfach wie ein "normales" Programm im laufenden Betrieb neu starten. Deshalb greifen Änderungen an einer Plist erst nach einem Neustart -- oder aber, wenn Notifications gesendet werden (Wie z.B. hier nach dem Trennen und Anmelden der Maus oder einem Log Out)

AppleScript und auch kein "irgendein Terminalbefehl" hat direkten Zugriff auf diese Kext, weil einfach mal das nötige (in Cocoa geschriebene) Command-Line Tool fehlt.

Allerdings hat AppleScript mittlerweile Zugriff auf einige Systemeinstellungen. Wie z.B. Expose/Spaces oder Netzwerk. (Leider aber nicht auf die Systemeinstellung Maus -- Weshalb du ja nur ein GUI Script im Netz gefunden hast)
Sprich: Mit AppleScript kann man in bestimmten Systemeinstellungen Veränderungen vornehmen, die dann von System Preferences weitergeleitet werden.

Gruß
 
Die Antwort zu deiner letzten Frage steht in #6.
Du meinst wohl #7, oder? #6 ist ja von mir. ;-)

Ja, genau. Und die Notification sagt dem Programm (Programm im weitesten Sinne, hier also Treiber), dass sich etwas geändert hat und dass das Programm sich bitte danach richten soll.

Hmm …
Kann man denn Einstellungen in den System Preferences per AppleScript oder Terminal vornehmen, ohne dass das GUI geöffnet wird? Und dass die System Preferences sich dann um die Notifications kümmern? So in der Art:

Code:
tell application "system preferences“ with no gui
    set maus scrolling to false
end tell
 
Ja, das stimmt schon, das ist mir durchaus klar. Aber es gibt ja auch Programme die ohne GUI gestartet werden können. ;-)
 
Zurück
Oben Unten