keystroke vs key code (osascript via Remote Desktop)

Hi all,

A while back, I wrote a small web app to convert a line of text into the corresponding key code. Someone suggested using keystroke instead, which I had completely forgotten at the time but had a nagging feeling as to why I wasnt using it. It turns out, the keystroke command doesn’t work when executed via osascript in Remote Desktop.

At least, it doesn’t work for me. Can anyone else verify this? For example, in a password dialog box:

Doesn’t work:

tell application "System Events"
    keystroke "myPassword"
    key down return
end tell

Works:

tell application "System Events"
    key code {46, 16}
    key code {35} using shift
    key code {0, 1, 1, 13, 31, 15, 2}
    key down return
end tell

Interestingly enough, keystroke will work just fine if the script is run locally on the machine and not through Remote Desktop and osascript.

Any clues? Thanks,
-Rob

Did you try something like this?


tell application "System Events" to tell process "WhateverItIs" to keystroke "myPassword" & return

Adam’s right.

I don’t think - as far as I know - something like ‘key down’ exists.
I’ve tested his snippet (locally, as I’m on a 56K line right now) on my Remote Desktop’s “Computer Info’s password field” and works fine


tell application "System Events" to tell process (path to frontmost application as string) to keystroke "myPassword" & return

key code works the same fine too


tell application "System Events" to tell process (path to frontmost application as string) to key code {46, 16, 35, 0, 1, 1, 13, 31, 15, 2, 36}
--shift, skipped  on purpose just for to make testing easier

Yannis

Hello

It appears that to issue keystrokes we must say to which process we are speaking.
It seems that it is not always required with key codes.

But when we know that I continue to think that keystroke which is not dependant of the active layout is better than key code.

On a physical french keyboard with U.S layout, key code {46, 16, 35, 0, 1, 1, 13, 31, 15, 2, 36} sends: “mypassword” & return

On a physical french keyboard with french layout it sends “,ypqsszord” & return

On a physical french keyboard with french layout, keystroke “myPassword” & return sends “myPassword” & return
On a physical french keyboard with selected U.S layout it sends: “;yPqsszord” & return
What is it sending on a physical english keyboard ? I assumes that it is “myPassword” & return

Yvan KOENIG (from FRANCE samedi 30 septembre 2006 08:37:27)

Thanks for the feedback. I’ll try Adam’s suggestion, then. Also, I’m not worried about keyboard layouts. The labs are all identical eMacs with U.S. keyboard.

Thanks again,
-Rob

Regarding that keycode conversion remains a weird pony (I am still looking for a conversion table), why not go for an ASCII based routine here…?

The following routine works here


set pw to "MyPasswordOrAnyString"

repeat with h in pw
	set r to ASCII number of h
	do shell script "sleep 0,2"
	tell application "System Events" to tell process (path to frontmost application as string) to keystroke (ASCII character r)
end repeat

and might be anhanced with


using (command down)

Have a look at KeyboardSee for international key codes.

Thanks Adam, that helped me to the following character → keycode conversion routine.
However, it is not very fast when converting long strings.
I am almost sure that this can be done more efficiently, but how…?
It discerns capitals (adding the shift code) and special keys need to go between brackets:


chartoISOKeyCode("Amsterdam[enter]")

to chartoISOKeyCode(x)
	set vect to {{"esc", "35"}, {"F1", "7A"}, {"F2", "78"}, {"F3", "63"}, {"F4", "76"}, {"F5", "60"}, {"F6", "61"}, {"F7", "62"}, {"F8", "64"}, {"F9", "65"}, {"F10", "6D"}, {"F11", "67"}, {"F12", "6F"}, ¬
		{"§", "0A"}, {"1!", "12"}, {"2@", "13"}, {"3#", "14"}, {"4$", "15"}, {"5%", "17"}, {"6^", "16"}, {"7&", "1A"}, {"8*", "1C"}, {"9(", "19"}, {"0)", "1D"}, {"-_", "1B"}, {"=+", "18"}, {"backspace", "33"}, ¬
		{"tab", "30"}, {"qQ", "0C"}, {"wW", "0D"}, {"eE", "0E"}, {"rR", "0F"}, {"tT", "11"}, {"yY", "10"}, {"uU", "20"}, {"iI", "22"}, {"oO", "1F"}, {"pP", "23"}, {"[{", "21"}, {"]}", "1E"}, {"Return", "24"}, ¬
		{"capslock", "39"}, {"aA", "00"}, {"sS", "01"}, {"dD", "02"}, {"fF", "03"}, {"gG", "05"}, {"hH", "04"}, {"jJ", "26"}, {"kK", "28"}, {"lL", "25"}, {";:", "29"}, {"'\"", "27"}, {"\\'|", "2A"}, ¬
		{"shift", "38"}, {"`~", "32"}, {"zZ", "06"}, {"xX", "07"}, {"cC", "08"}, {"vV", "09"}, {"bB", "0B"}, {"nN", "2D"}, {"mM", "2E"}, {",<", "2B"}, {".>", "2F"}, {"/?", "2C"}, ¬
		{"Fn", "3F"}, {"ctrl", "3B"}, {"opt", "3A"}, {"cmd", "37"}, {" ", "31"}, {"enter", "4C"}, {"leftarrow", "7B"}, {"downarrow", "7D"}, {"uparrow", "7E"}, {"rightarrow", "7C"}}
	set KcodeStr to ""
	set skipflag to false
	repeat with h from 1 to count of characters of x
		set hStr to x's character h
		if h > 2 and x's character (h - 1) as string = "]" then set skipflag to false
		if x's character h as string = "[" then
			set t to ""
			repeat with k from h + 1 to count of characters of x
				if x's character k = "]" then exit repeat
				set t to (t & x's character k) as string
			end repeat
			set hStr to t
		end if
		if not skipflag then
			considering case
				if number of characters of hStr > 1 then
					set skipflag to true
					set namedkeys to ""
				else
					set namedkeys to {"esc", "tab", "backspace", "capslock", "return", "enter", "shift", "cmd", "opt", "ctrl", "Fn", "leftarrow", "rightarrow", "downarrow", "uparrow"}
				end if
				--	display dialog (hStr & return & skipflag) as string
				repeat with j in items of vect
					if hStr is in j's item 1 and j's item 1 is not in namedkeys then
						set prefix to ""
						if number of characters of j's item 1 = 2 and (hStr) is in character 2 of j's item 1 then set prefix to "38 "
						set KcodeStr to KcodeStr & prefix & j's item 2 & ","
						exit repeat
					end if
				end repeat
			end considering
		end if
	end repeat
	return KcodeStr's text 1 thru -2
end chartoISOKeyCode

Hello

For those who may be interested, the vect for a french keyboard would be (if I made no mistake)

set vect to {{“esc”, “35”}, {“F1”, “7A”}, {“F2”, “78”}, {“F3”, “63”}, {“F4”, “76”}, {“F5”, “60”}, {“F6”, “61”}, {“F7”, “62”}, {“F8”, “64”}, {“F9”, “65”}, {“F10”, “6D”}, {“F11”, “67”}, {“F12”, “6F”}, ¬
{“§6”, “16”}, {“&1”, “12”}, {“é2”, “13”}, {(ASCII character 22) & “3”, “14”}, {“'4”, “15”}, {“5(”, “17”}, {“§6”, “16”}, {“è7”, “1A”}, {“!8”, “1C”}, {“ç9”, “19”}, {“à 0”, “1D”}, {“)°”, “1B”}, {“-_”, “18”}, {“backspace”, “33”}, ¬
{“tab”, “30”}, {“aA”, “0C”}, {“zZ”, “0D”}, {“eE”, “0E”}, {“rR”, “0F”}, {“tT”, “11”}, {“yY”, “10”}, {“uU”, “20”}, {“iI”, “22”}, {“oO”, “1F”}, {“pP”, “23”}, {“^¨”, “21”}, {“$*”, “1E”}, {“Return”, “24”}, ¬
{“capslock”, “39”}, {“qQ”, “00”}, {“sS”, “01”}, {“dD”, “02”}, {“fF”, “03”}, {“gG”, “05”}, {“hH”, “04”}, {“jJ”, “26”}, {“kK”, “28”}, {“lL”, “25”}, {“mM”, “29”}, {“ù%”, “27”}, {“`£”, “2A”}, ¬
{“shift”, “38”}, {“<>”, “32”}, {“wW”, “06”}, {“xX”, “07”}, {“cC”, “08”}, {“vV”, “09”}, {“bB”, “0B”}, {“nN”, “2D”}, {“,?”, “2E”}, {“;.”, “2B”}, {“:” & “/”, “2F”}, {“=+”, “2C”}, ¬
{“Fn”, “3F”}, {“ctrl”, “3B”}, {“opt”, “3A”}, {“cmd”, “37”}, {" ", “31”}, {“enter”, “4C”}, {“leftarrow”, “7B”}, {“downarrow”, “7D”}, {“uparrow”, “7E”}, {“rightarrow”, “7C”}}

I coded {“:” & “/”, “2F”} to get rid of a smiley’s translation :wink:

Yvan KOENIG (from FRANCE mardi 3 octobre 2006 14:19:55)

For either language (or for both with a suitable adder to the arguments to the handler), putting the vector in a script property helps speed:


chartoISOKeyCode("Amsterdam[enter]")

to chartoISOKeyCode(x)
	script v
		property vect : {{"esc", "35"}, {"F1", "7A"}, {"F2", "78"}, {"F3", "63"}, {"F4", "76"}, {"F5", "60"}, {"F6", "61"}, {"F7", "62"}, {"F8", "64"}, {"F9", "65"}, {"F10", "6D"}, {"F11", "67"}, {"F12", "6F"}, ¬
			{"§", "0A"}, {"1!", "12"}, {"2@", "13"}, {"3#", "14"}, {"4$", "15"}, {"5%", "17"}, {"6^", "16"}, {"7&", "1A"}, {"8*", "1C"}, {"9(", "19"}, {"0)", "1D"}, {"-_", "1B"}, {"=+", "18"}, {"backspace", "33"}, ¬
			{"tab", "30"}, {"qQ", "0C"}, {"wW", "0D"}, {"eE", "0E"}, {"rR", "0F"}, {"tT", "11"}, {"yY", "10"}, {"uU", "20"}, {"iI", "22"}, {"oO", "1F"}, {"pP", "23"}, {"[{", "21"}, {"]}", "1E"}, {"Return", "24"}, ¬
			{"capslock", "39"}, {"aA", "00"}, {"sS", "01"}, {"dD", "02"}, {"fF", "03"}, {"gG", "05"}, {"hH", "04"}, {"jJ", "26"}, {"kK", "28"}, {"lL", "25"}, {";:", "29"}, {"'\"", "27"}, {"\\'|", "2A"}, ¬
			{"shift", "38"}, {"`~", "32"}, {"zZ", "06"}, {"xX", "07"}, {"cC", "08"}, {"vV", "09"}, {"bB", "0B"}, {"nN", "2D"}, {"mM", "2E"}, {",<", "2B"}, {".>", "2F"}, {"/?", "2C"}, ¬
			{"Fn", "3F"}, {"ctrl", "3B"}, {"opt", "3A"}, {"cmd", "37"}, {" ", "31"}, {"enter", "4C"}, {"leftarrow", "7B"}, {"downarrow", "7D"}, {"uparrow", "7E"}, {"rightarrow", "7C"}}
	end script
	set KcodeStr to ""
	set skipflag to false
	repeat with h from 1 to count of characters of x
		set hStr to x's character h
		if h > 2 and x's character (h - 1) as string = "]" then set skipflag to false
		if x's character h as string = "[" then
			set t to ""
			repeat with k from h + 1 to count of characters of x
				if x's character k = "]" then exit repeat
				set t to (t & x's character k) as string
			end repeat
			set hStr to t
		end if
		if not skipflag then
			considering case
				if number of characters of hStr > 1 then
					set skipflag to true
					set namedkeys to ""
				else
					set namedkeys to {"esc", "tab", "backspace", "capslock", "return", "enter", "shift", "cmd", "opt", "ctrl", "Fn", "leftarrow", "rightarrow", "downarrow", "uparrow"}
				end if
				--	display dialog (hStr & return & skipflag) as string
				repeat with j in items of v's vect
					if hStr is in j's item 1 and j's item 1 is not in namedkeys then
						set prefix to ""
						if number of characters of j's item 1 = 2 and (hStr) is in character 2 of j's item 1 then set prefix to "38 "
						set KcodeStr to KcodeStr & prefix & j's item 2 & ","
						exit repeat
					end if
				end repeat
			end considering
		end if
	end repeat
	return KcodeStr's text 1 thru -2
end chartoISOKeyCode