AppleScript: Wie überprüfe ich, ob die Zwischenablage aus einer Datei (anstelle von Text) besteht?

Wenn ich richtig verstehe, gibt es zwei Arten von Inhalten, die in die globale (systemweite) Mac-Zwischenablage kopiert werden können:

  • text

oder

  • file

Obwohl es sich um zwei verschiedene, diskrete Datentypen handelt, teilen sie sich dieselbe Zwischenablage. Wenn Sie beispielsweise ein Bild filein Ihrer Zwischenablage haben und dann einen textSatz kopieren, überschreibt der Satz die Bilddatei und umgekehrt. Bitte korrigieren Sie mich, wenn ich falsch liege.

Meine Frage ist, wie kann ich mit AppleScript feststellen, ob die Zwischenablage keine enthält text?

Der Kontext meiner Frage ist eine AppleScript-.scpt-Datei, die den ausgewählten Text in der Systemstimme mit einer bestimmten Lautstärke spricht. Der markierte Text wird in die Zwischenablage kopiert und dann über den Befehl gesprochen say. Das Skript wird per Tastendruck über FastScripts.app ausgelöst.

Hin und wieder erhalte ich einen Fehlerdialog, der besagt: "Fehlernummer: -1728". Dieser Fehler tritt auf, wenn ich, anstatt texthervorgehoben zu werden, eine tatsächliche hervorgehoben oder ausgewählt habe file. Die Sprachfunktion von Mac kann kein file; Sprache kann nur verbalisieren text.

Ich möchte also eine if...thenAnweisung in meinem Skript erstellen, um diesen Fehler abzufangen. Idealerweise möchte ich dann die filein konvertieren text, wenn möglich so, wie es TextEdit tut.

Ihre erste Annahme ist falsch: Text oder Datei (wahrscheinlich meinen Sie wirklich xor ). Es ist viel komplizierter. Sie können den Inhalt der Zwischenablage mit der Apple (Xcode) App „Clipboard Viewer“ überprüfen. Es ist in Hilfstools für Xcode 7 verfügbar.
Man könnte auch einfach einen Automator-Dienst erstellen (der einer Tastenkombination über das Systemeinstellungsfenster Tastatur zugewiesen wird), der den ausgewählten Text in jeder Anwendung empfängt und dann die Aktionen Computerlautstärke einstellen und Text sprechen ausführt , ohne den ausgewählten Text kopieren zu müssen die Zwischenablage. (Natürlich können Sie gute Gründe haben, stattdessen Ihr AppleScript zu verwenden!)
@BigMac 1. Mein AppleScript-Code ermöglicht es mir, die Sprache mit demselben Tastendruck zu stoppen, mit dem ich die Sprache starte. 2. Mein Code wirkt sich nicht wirklich auf die Systemlautstärke aus; es definiert die Lautstärke des Sprechvorgangs als Prozentsatz der aktuellen Systemlautstärke. 3. Das Auslösen eines systemweiten Dienstes per Tastaturkürzel ist unzuverlässig. Siehe: Tastaturkürzel für den Dienst funktioniert nur, nachdem ich den Dienst manuell ausgeführt habe . FastScripts.app, OTOH, ist zuverlässig. Aber FastScripts können natürlich nur .scpt-Dateien auslösen, keine Automator Service-Dateien.
@rubik'ssphere Danke für die Erklärung; Ich kenne keine Möglichkeit, #1 in Automator zu machen, also ist das Grund genug, AppleScript zu verwenden! #3 würde auch einen Automator-Dienst ausschließen, aber zum Glück habe ich dieses Problem (noch) nicht erlebt. Nr. 2 könnte wahrscheinlich in einer Run AppleScript- Aktion in Automator ausgeführt werden (anstatt die von mir erwähnten Aktionen zu verwenden). Ich würde gerne Ihr endgültiges Skript sehen, wenn Sie bereit sind, es zu teilen, da ich auch oft Apples Text-to-Speech verwende.
@BigMac (1/2) Das Herzstück meines Codes ist die geniale Lösung, die von jackjr300 hier bereitgestellt wird: AppleScript: Kann überprüft werden, ob Speech gerade ausgeführt wird? . Um die Lautstärke der Sprache als Prozentsatz der aktuellen Systemlautstärke festzulegen (ich habe 35 % gewählt), siehe: Wie ändere ich die Lautstärke von „Sagen“ in AppleScript? . Ich habe einen Befehlszeilenfehler entdeckt, also siehe hier für eine Problemumgehung:
(2/2) Wie umgeht man den Befehlsfehler „say“ beim Einstellen der Lautstärke? Schließlich lässt die Antwort von @user3439894 auf genau diesen Beitrag das Skript den Dateinamen einer ausgewählten Datei sprechen : AppleScript: Wie kann überprüft werden, ob die Zwischenablage aus einer Datei (anstelle von Text) besteht? Wenn Sie dies alles zusammenfügen, haben Sie meine aktuelle AppleScript-Datei erstellt.

Antworten (1)

Wenn die Zwischenablage ein Dateiobjekt enthält , clipboard infoenthält sie zB «class furl»(eine Datei-URL) zusammen mit vielen anderen Klassen.

Der folgende Beispielcode überprüft das Vorhandensein von «class furl»in clipboard info:

if ((clipboard info) as string) contains "«class furl»" then
    say "the clipboard contains a file named " & (the clipboard as string)
else
    say "the clipboard does not contain a file"
end if

Aktualisieren:

Wie ich in einem meiner Kommentare erwähnt habe, gibt es andere Möglichkeiten, dies zu codieren, und dieser Ansatz gibt entweder eine leere Liste oder eine Liste mit einer Liste zurück , was schneller sein sollte als die 14, die das erste Beispiel zurückgibt, wenn es eine enthält Datei . Wenn die Zwischenablage keine Datei enthält , ist die zurückgegebene Liste leer und es tritt ein Fehler auf cbFile, falseund wenn sie nicht leer ist, wird sie auf gesetzt true, was dann im folgenden Beispiel getestet wird.

try
    (item 1 of (clipboard info for «class furl»))
    set cbFile to true
on error
    set cbFile to false
end try
if cbFile then
    say "the clipboard contains a file named " & (the clipboard as string)
else
    say "the clipboard does not contain a file"
end if

Übrigens habe ich den purge Befehl im Terminal zwischen dem Testen dieser beiden Beispiele ausgeführt, und es fühlte sich an, als wäre das zweite Beispiel etwas schneller, jedoch YMMV.

Wissen Sie auch, wie Sie nur den Dateinamen (nicht den vollständigen Pfad) als Text einer Datei erhalten, die sich in der Zwischenablage befindet? Wenn die if-Bedingung erfüllt ist: if ((clipboard info) as string) contains "«class furl»"dann möchte ich mein Skript auf sayden Dateinamen der Zwischenablage-Datei setzen.
Lassen Sie mich wissen, wenn Sie der Meinung sind, dass die Frage in meinem obigen Kommentar einen eigenen Beitrag verdient.
@rubiks Sphäre, ich habe die Antwort aktualisiert, um die in Ihrem Kommentar festgelegte Bedingung zu behandeln. Übrigens, wenn Sie den vollständig qualifizierten Pfadnamen möchten, müssen Sie Cocoa-AppleScript und NSPasteboard verwenden, die ich nicht als reguläres AppleScript kenne.
Eine andere enge Frage wäre am besten, @rubik'ssphere . Die beiden hier in Kommentaren zu verlinken wäre auch schön. Ich werde die Frage, die Sie hier gepostet haben, bearbeiten, um das Thema hier klarer zu machen.
Erläutern Sie dem Down-Voter bitte einen berechtigten Grund dafür. Beantwortet dies nicht die gestellte Frage? Haben Sie eine bessere Antwort als eine ungerechtfertigte Ablehnung!?
@ user3439894 Ihre Lösung funktioniert gut. Aber ich bemerke, dass es eine kurze Verzögerung gibt, bevor das Skript spricht: "Die Zwischenablage enthält eine Datei namens Dateiname." Kann ich irgendetwas tun, um diese Verzögerung zu verkürzen oder zu beseitigen?
@rubik's sphere, Wie lange eine Verzögerung? ... Wenn ich diesen Beispielcode im Skripteditor so ausführe, wie er ist, bemerke ich wirklich keine Verzögerung. Bemerken Sie eine Verzögerung bei diesem Beispielcode im Skripteditor, wie er ist, oder haben Sie dieses Beispiel genommen und überarbeitet, um es an Ihre Anforderungen im größeren Skript anzupassen, und stellen Sie dort eine Verzögerung fest? Im ersten Fall gibt es mehr als eine Möglichkeit, diesen Code zu schreiben, und ich habe verschiedene Codierungen getestet, bemerke aber wirklich keine Verzögerung auf meinem System. Wenn letzteres der Fall ist, dann kann ich, ohne den zu testenden Code zu sehen, wirklich nichts sagen ( Code- Wortspiel beabsichtigt).
@ user3439894 Wenn ich Ihren Code wörtlich in Script Editor.app ausführe, gibt es eine Verzögerung von 1 Sekunde, bevor „Die Zwischenablage enthält eine Datei mit dem Namen ...“ gesprochen wird, aber „Die Zwischenablage enthält keine Datei“ wird sofort gesprochen. Dies gilt unabhängig vom Typ oder Speicherort der Datei in der Zwischenablage. Erleben Sie die Verzögerung auf Ihrem System nicht? Dies ist offensichtlich keine große Verzögerung, aber es ist lang genug, dass ich die Verzögerung jedes Mal bemerke. Wäre es mir möglich, die andere(n) Codierungsmethode(n) zu testen?
@rubiks Sphäre, jetzt, da ich weiß, dass Sie einen Unterschied zwischen den beiden Zuständen vergleichen, ist das zu erwarten, da mehr Verarbeitung stattfindet, wenn es als wahr ausgewertet wird. Wenn falsch, kann die Rückgabe von clipboard infonur 4 Klassen enthalten und wenn wahr, kann sie viel mehr, z. B. 14, Klassen enthalten. All dies muss aufgezählt werden, und bei einigen davon kann es länger dauern, sie aufzuzählen, als bei anderen, was die erwartete Verzögerung weiter erhöht. Damit allein startet die Verzögerung diff. Auch wenn wahr, wird die Zwischenablage nach dem Dateinamen als Zeichenfolge abgefragt, wodurch mehr zum Verzögerungsunterschied hinzugefügt wird. Ist das sinnvoll?
@rubik's sphere, ich habe die Antwort aktualisiert und ein weiteres Beispiel hinzugefügt, damit Sie testen können, ob es schneller ist.
@ user3439894 Ja, das macht Sinn. Danke für die ausführliche Erklärung. Ich bin immer noch überrascht, dass eine so leistungsstarke und fortschrittliche Maschine diese relativ einfache Aufgabe nicht sofort ausführen kann. Ich nehme an, dass ein ineffizienter Code von Apple schuld ist. Ich habe festgestellt, dass Ihre alternative Methode nicht schneller ist als die ursprüngliche Methode, soweit ich das beurteilen kann. Die neue Methode hat immer noch eine Verzögerung von 1 Sekunde. Ich kann die Laufzeit nicht auf die Millisekunde genau messen. Danke für all deine Hilfe.
@rubik's sphere, FWIW Speichern beider Codeversionen als .scpt mit Modifizieren des falschen Zweigs, also sagen wir, würde genau dasselbe sagen wie der wahre Zweig, um den besten Vergleich zu erzielen, und das Ausführen mit als Argument von , es gab osascripteinen timeUnterschied zwischen den 2 Versionen. Ich habe Terminal geschlossen/geöffnet und den purgeBefehl zwischen jedem Durchlauf verwendet, und als alles gesagt war, hatte eine erledigte ver1 einen Unterschied von 0,719 s zwischen dem T / F-Zweig und ver2 hatte einen Unterschied von 0,363 s zwischen dem T / F-Zweig im Vergleich zu einem 0,356 s Unterschied zwischen den einzelnen Versionen. Während ver2 technisch schneller war, ist der Unterschied vernachlässigbar.
@user3439894 Interessante Analyse. In diesem Fall werde ich mit der alternativen Methode gehen.