Ist es möglich, Sonderzeichen in AppleScript zu tippen?

Der Fehler:

Bei bestimmten Sonderzeichen und Symbolen erkennt AppleScript nicht keystrokedas eigentliche Zeichen und gibt stattdessen einfach den Buchstaben ein a.


Ein Beispiel:

Der folgende AppleScript-Code:

tell application "System Events" to keystroke "² ³ é ½ ₭"

gibt die folgende Textzeichenfolge ein (egal in welcher Anwendung ich mich befinde):

a a a a a

Eine Problemumgehung:

Man kann den Text effektiv "eintippen", indem man die Sonderzeichen in die Zwischenablage legt und dann die Zwischenablage wie folgt einfügt:

set the clipboard to "² ³ é ½ ₭"
tell application "System Events" to keystroke "v" using command down

Ich vermeide es, die obige Methode zu verwenden, um Text in AppleScript in die Zwischenablage zu legen, da die Zwischenablage dabei zwangsläufig in Rich-Text konvertiert wird.

Ich ziehe es vor, die hier bereitgestellte Methode anzuwenden , um sicherzustellen, dass einfacher Text in der Zwischenablage abgelegt wird. Aber diese Methode wandelt Sonderzeichen in Mojibake um.

Wenn Sie beispielsweise dieselbe Zeichenfolge wie oben verwenden, fügt diese Methode den folgenden Text in die Zwischenablage ein:

² ³ é ½ ₭

Sie können dieses Problem jedoch manuell berücksichtigen, indem Sie replace_charsfür jedes Sonderzeichen eine Anweisung hinzufügen.


Die Frage:

Gibt es eine Möglichkeit, Sonderzeichen über AppleScript einzugeben, ohne die Zwischenablage einbeziehen zu müssen?

Gibt es zum Beispiel eine Möglichkeit, die gewünschten Sonderzeichen irgendwo in eine "Bank" oder Systemdatei einzufügen, damit die System EventsAnwendung sie kennt?


Antworten (5)

Es ist mit CoreGraphics ( CGEventPost) möglich, es ist eine C - API (es funktioniert nicht in einem Cocoa-AppleScript), aber es ist möglich, eine ausführbare Datei von einem AppleScript aufzurufen.


Hier ist die Methode zum Erstellen der ausführbaren Datei mit Xcode (Version 8.3.3):

Sie können es selbst tun (Sie können Xcode aus dem App Store herunterladen ) oder eine vertrauenswürdige Person bitten, die ausführbare Datei zu erstellen.

1- Öffnen Sie Xcode, wählen Sie im Menü „ Datei “ -> „ Neu “ -> „ Projekt …“Geben Sie hier die Bildbeschreibung ein


2- Wählen Sie macOS und das Befehlszeilentool aus und klicken Sie auf die Schaltfläche „ Weiter “.Geben Sie hier die Bildbeschreibung ein


3- Benennen Sie es TypeCharacters, wählen Sie Objective-C als Sprache aus und klicken Sie auf die Schaltfläche " Weiter ".Geben Sie hier die Bildbeschreibung ein


4- Speichern Sie das Projekt im gewünschten Ordner.


5- Wählen Sie im Fenster von Xcode das main.mSymbol aus, löschen Sie den Text im Fenster und fügen Sie einen dieser beiden Codes ein:

Der Code benötigt aufgrund eines Fehlers eine Schleife, die CGEventKeyboardSetUnicodeString()Methode schneidet eine Zeichenfolge ab, die zwanzig Zeichen überschreitet, oder es ist eine Grenze (nicht dokumentiert).

Dieser Code verwendet eine Schleife, um bei jeder Iteration eine Liste von Zeichen einzugeben, die Liste kann ein bis zwanzig Zeichen enthalten. (Es ist schnell, 1 Sekunde, um 2400 Zeichen in ein TextEdit-Dokument auf meinem Computer einzugeben.)

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        if (argc > 1) {
            NSString *theString = [NSString stringWithUTF8String:argv[1]];
            NSUInteger len = [theString length];
            NSUInteger n, i = 0;
            CGEventRef keyEvent = CGEventCreateKeyboardEvent(nil, 0, true);
            unichar uChars[20];
            while (i < len) {
                n = i + 20;
                if (n>len){n=len;}
                [theString getCharacters:uChars range:NSMakeRange(i, n-i)];
                CGEventKeyboardSetUnicodeString(keyEvent, n-i, uChars);
                CGEventPost(kCGHIDEventTap, keyEvent); // key down
                CGEventSetType(keyEvent, kCGEventKeyUp);
                CGEventPost(kCGHIDEventTap, keyEvent); // key up (type 20 characters maximum)
                CGEventSetType(keyEvent, kCGEventKeyDown);
                i = n;
                [NSThread sleepForTimeInterval:0.004]; // wait 4/1000 of second, 0.002 it's OK on my computer, I use 0.004 to be safe, increase it If you still have issues
            }
            CFRelease(keyEvent);
        }
    }
    return 0;
}

Dieser Code verwendet eine Schleife, um bei jeder Iteration ein Zeichen einzugeben (er ist langsamer als der erste Code).

#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        if (argc > 1) {
            NSString *theString = [NSString stringWithUTF8String:argv[1]];
            UniChar uChar;
            CGEventRef keyEvent = CGEventCreateKeyboardEvent(nil, 0, true);
            for (int i = 0; i < [theString length]; i++)
            {
                uChar = [theString characterAtIndex:i];
                CGEventKeyboardSetUnicodeString(keyEvent, 1, &uChar);
                CGEventPost(kCGHIDEventTap, keyEvent); // key down
                CGEventSetType(keyEvent, kCGEventKeyUp);
                CGEventPost(kCGHIDEventTap, keyEvent); // key up (type the character)
                CGEventSetType(keyEvent, kCGEventKeyDown);
                [NSThread sleepForTimeInterval:0.001]; // wait 1/1000 of second, no need of this line on my computer, I use 0.001 to be safe, increase it If you still have issues
            }
            CFRelease(keyEvent);
        }
    }
    return 0;
}

Hinweis : Dieser Code funktioniert auf macOS Sierra und sollte auf El Capitan funktionieren , aber nicht auf einem älteren Betriebssystem .

Geben Sie hier die Bildbeschreibung ein


6- Wählen Sie das Menü " Produkt " --> " Bauen ".


7- Wählen Sie das TypeCharactersSymbol im Produktordner aus, klicken Sie mit der rechten Maustaste und wählen Sie im Kontextmenü das Menü „ Im Finder anzeigen “.

Geben Sie hier die Bildbeschreibung ein


8- Verschieben Sie aus dem Finder die Datei „ TypeCharacters “ in den gewünschten Ordner, beenden Sie Xcode , das ist alles.


Rufen Sie in einem AppleScript die ausführbare Datei wie folgt auf

set myString to "ùéèà ² ³ é ½ ₭ "
do shell script "'/full path/of/TypeCharacters' " & quoted form of myString
Unglaubliche Antwort. Diese Lösung funktioniert auch unter OS X 10.11.6 einwandfrei. Ich könnte mir keine bessere Lösung vorstellen. Ich schätze auch die detaillierten Screenshots. Vielen, vielen Dank!!!
Ich habe einen Fehler entdeckt: Wenn die Länge von myString20 Zeichen überschreitet, wird der String abgeschnitten. Das heißt, jeglicher Text, der auf das zwanzigste Zeichen folgt, wird nicht eingegeben. Wissen Sie, wie Sie das beheben können?
Jetzt verwende ich eine Schleife, um jedes Zeichen einzugeben (getestet mit einer Zeichenfolge von 2000 oder mehr Zeichen). Ich habe den Code in meiner Antwort aktualisiert.
Ihre neue Lösung hat das Problem gelöst. Vielen Dank! Nebenbei bemerkt, Sie haben die #import <Foundation/Foundation.h>Zeile in Ihrer Bearbeitung aus Ihrem Code entfernt, aber diese Zeile ist für einen erfolgreichen Build immer noch erforderlich. Ich weiß, dass diese Codezeile standardmäßig vorhanden ist, aber es gibt einige Mehrdeutigkeiten, weil Ihre Anweisungen sagen, "den Text im Fenster zu löschen".
Ich denke, die neue Lösung hat einen neuen Fehler. Von Zeit zu Zeit fehlt dem eingegebenen Text ein Zeichen oder die Reihenfolge des Textes wird geändert. Dies tritt unabhängig von der Zeichenfolgenlänge auf. Hier ist ein echtes Beispiel: Die Zeichenfolge, die der TypeCharacters-Datei gegeben wurde, war, = 278,932aber die folgende Zeichenfolge wurde eingegeben: =2 78,93.
Keine Fehler hier. Vielleicht eine (Substitution, eine Transformation oder die korrekte Schreibweise automatisch) im Vordergrund liegende Anwendung. Überprüfen Sie die Textersetzung in den "Systemeinstellungen". Verwenden Sie andernfalls den Debug-Code (in meiner Antwort).
Vielleicht ( bei starker CPU-Last ) braucht der Code eine kleine Verzögerung zwischen jedem KeyDown . Versuchen Sie das: Fügen Sie diese Zeile am Ende der Schleife hinzu [NSThread sleepForTimeInterval:0.02]; // wait 2/100 of second, increase it If you still have issues.. Ich habe den Code in meiner Antwort aktualisiert. Ich füge meiner Antwort einen weiteren Code hinzu (dieser Code kann bei jeder Iteration 20 Zeichen anstelle von einem Zeichen eingeben, versuchen Sie es.
Hmm. Es ist definitiv kein Problem mit der Textersetzung / -transformation. Außerdem tritt das Problem auch dann auf, wenn keine andere Anwendung geöffnet ist, sodass es nicht von der CPU-Auslastung abhängt (und es tritt in jeder beliebigen Anwendung auf, von TextEdit bis Google Chrome). Ich habe mein NVRAM und SMC zurückgesetzt; das Problem besteht weiterhin. Vielleicht ist es ein El Capitan-Problem? Übrigens, ich benutze ein Retina MacBook Pro von Anfang 2013, also wird mein Computer vielleicht einfach alt und träge.
Was auch immer für die Ursache des Problems verantwortlich ist, eine Ihrer beiden neuen Lösungen scheint das Problem vollständig behoben zu haben. Hier sind GIFs, die die Ergebnisse auf meinem Computer zeigen: Wenn ich den ersten Codeblock in Ihrer aktuellen Antwort verwende. Wenn ich den Debug-Code verwende . Wenn ich den 3. Codeblock verwende (den ich mit einer kürzeren Verzögerung modifiziert habe).
Ich freue mich, dass Ihr Problem gelöst wurde. Auf meinem Computer: Um bei jeder Iteration ein Zeichen einzugeben, ist die sleepForTimeInterval:Methode nicht erforderlich, aber dies ist erforderlich, um bei jeder Iteration eine Liste von Zeichen einzugeben (wenn die Zeichenfolge natürlich mehr als zwanzig Zeichen enthält). Ich habe meine Antwort aktualisiert (Reinigung).
Ich habe festgestellt, dass dieses TypeCharactersSkript keine Zeilenumbruchzeichen eingeben kann. Wenn die Zeichenfolge einen Zeilenumbruch enthält, wird die Zeichenfolge überhaupt nicht eingegeben. Wissen Sie, wie man Zeilenumbrüche im getippten Text beibehält? Danke dir.
Da dies tatsächlich das Drücken von Tasten simuliert, können schlimme Dinge passieren, wenn Sie währenddessen eine Zusatztaste drücken?

Ein Workaround (mit der Zwischenablage):

1 - Sie können eine Kakaomethode aus einer Schale verwenden:

set tString to "² ³ é ½ ₭"
my stringToClipboard(tString)
tell application "System Events" to keystroke "v" using command down

on stringToClipboard(t1)
    do shell script "/usr/bin/python -c 'import sys;from AppKit import NSPasteboard, NSPasteboardTypeString; cb=NSPasteboard.generalPasteboard();cb.declareTypes_owner_([NSPasteboardTypeString], None);cb.setString_forType_(sys.argv[1].decode(\"utf8\"), NSPasteboardTypeString)' " & quoted form of t1
end stringToClipboard

2 - Oder ein Cocoa-AppleScript-Applet:

use framework "AppKit"
use scripting additions
set tString to "² ³ é ½ ₭"
my stringToClipboard(tString)
tell application "System Events" to keystroke "v" using command down

on stringToClipboard(t1)
    set ca to current application
    set cb to ca's NSPasteboard's generalPasteboard()
    cb's declareTypes:{ca's NSPasteboardTypeString} owner:(missing value)
    cb's setString:t1 forType:(ca's NSPasteboardTypeString)
end stringToClipboard

Um keystrokeeinem Zeichen zuzuordnen, muss dieses Zeichen einer tatsächlichen Taste auf Ihrer ausgewählten Tastatur zugeordnet werden.

Zum Beispiel kann ich keystroke é und ² ganz gut, weil ich das französische — PC -Tastaturlayout verwende. Eine standardmäßige amerikanische QWERTY-Tastatur verfügt jedoch nicht über diese Tasten und kann sie nicht verwenden keystroke.

Sie können alle Ihre Sonderzeichensätze wie folgt als Variablen definieren

on specialKeys(input)
    tell application "System Events"
        keystroke input
    end tell
end specialKeys


set characterSet1 to "²³é½₭ "
set characterSet2 to "³ "
set characterSet3 to "é "
set characterSet4 to "¬Ω "
set characterSet5 to "₭ "
set characterSet6 to characterSet1 & characterSet2 & characterSet3 & characterSet4 & characterSet5

specialKeys(characterSet1)
-- ² ³ é ½ ₭ is the result from calling specialKeys(characterSet1) After adding the text replacement for “a a a a a” in my keyboard preferences

Einige Sonderzeichen drücken korrekt, wenn Sie sie als Variablen festlegen. Alle Sonderzeichen, die Sie als Variablen festlegen, die nicht richtig auf Tastendruck reagieren, können Sie in den Systemeinstellungen für Ihre Tastatur „Textersetzungen“ hinzufügen.

Stellen Sie sicher, dass Sie alle Elemente auswählen und sie auf Ihren Desktop oder wohin auch immer ziehen. Dadurch wird eine .plist-Datei erstellt, die eine Sicherungskopie Ihrer ursprünglichen Einstellungen darstellt. Sie können diese Datei jederzeit zurückziehen.

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Stellen Sie dann im ScriptEditor sicher, dass Sie Textersetzungen im Untermenü „Ersetzungen“ des Bearbeitungsmenüs aktiviert haben.

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Die Problemumgehung " Textersetzung" funktioniert wie gewünscht in den meisten OS X-Anwendungen (z. B. TextEdit, Notes, Skripteditor usw.), aber ich hatte auf eine Lösung gehofft, die in jedem Textfeld in jeder Anwendung funktioniert. Viel verlangt, ich weiß! Ich denke immer noch, dass dies eine sehr clevere Lösung ist, also +1. Danke für die Antwort.

Wir können Nicht-ASCII-Zeichen mit der Zwischenablage eingeben:

tell application "System Events"
    set textBuffer to "² ³ é ½ ₭"
    repeat with i from 1 to count characters of textBuffer
        set the clipboard to (character i of textBuffer)
        delay 0.05
        keystroke "v" using command down
    end repeat
end tell