SendInput %userInput% causes my computer to do very weird stuff. Sometimes it logs off, sometimes my arrows of the keyboard get disabled, sometimes it runs cmd in windows an infinite times...
UPDATE:
this is the thing that gets inputed in the command line and runs:
runas /user:administrator cmd
UPDATE:
I think I almost got the problem, as such I edited the question to leave out what I deem to be irrelevant now.
When SendInput is happening, and the user is still inputting data in the keyboard, such as pressing the win-key, then this can cause the system to log off because win-key + l is a shortcut for that. Likewise must be for all the other things that are happening. Another observation is that SendInput skips certain characters, like {enter} etc. It only processes them at the end, when all the regular characters are put into place. I notice that at the end, SendInput is still busy doing stuff, perhaps some exotic characters it delayed till the end. Because the user think the output is complete, he ends up pressing the shortcut key again which in combination with the current sendInput is causing the system to crash.
UPDATE:
It also goes bezerk if there is a "!" to be send with SendInput.
This is one string I pasted to the copyboard:
dsjkfhjdsfsjdh!!!!!!!!!!!####################$$$$$$$$$$$%%%%%%%%%^^^^^^^^^^^^^&&&&&&&&&&&&&*****(((((((((())))))))))))____++++++++++++++++=======------------000000000000000099999988888.
But the output is WITHOUT the exclamation marks. Like this:
dsjkfhjdsfsjdh#######$$$$$$$$$$%%%%%%%%%&&&&&&&&&&&&*****(((((((((())))))))))))____+======------------000000000000000099999988888.
Why is that? Are there any other characters? Exclamation marks are important I feel, and I don't want to remove them. Are there any workarounds?
UPDATE:
It is more complicated than that. When I copy paste the above characters WITHOUT the exclamation marks, it still does weird stuff.
Here is some of the code that eventually userInput combines and sends away with SendInput:
StringReplace, contents, save_selection, ``, ````, All ; Do this replacement first to avoid interfering with the others below.
StringReplace, contents, contents, `r`n, %A_SPACE%, All ; Using `r works better than `n in MS Word, etc.
StringReplace, contents, contents, `;, ```;, All
;* loc_title origanally contains browser specification. Remove it.
StringGetPos, pos_delim, loc_title, - , R
length := StrLen(loc_title)
count := length - pos_delim
StringTrimRight, loc_title, loc_title, count
You could use sendraw instead of sendinput.
Here is what the docs say:
Raw mode: The SendRaw command interprets all characters literally
rather than translating {Enter} to an ENTER keystroke, ^c to
Control-C, etc. However, the normal rules for escape sequences,
variable references and expressions still apply since these are
processed before the command executes. To use raw mode with SendInput,
SendPlay, or SendEvent, write {Raw} as the first item in the string;
for example: SendInput {Raw}abc.
Then you don't have to worry about the ! or other control modifiers.
The reason that the exclamation mark character is an issue is because SendInput treats it as a code to press the Alt key.
There are several similar codes:
^ = Ctrl
+ = Shift
# = Windows key
You can find the others listed in the documentation for SendInput.
It seems like you want to send the raw text and not have SendInput look for these codes. You should be able to put {Raw} at the beginning of the userinput variable and it will ignore any codes in the rest of the characters.
If it is typing too slowly, you could put SetKeyDelay,-1 in your script to remove the key sending delay.
A good workaround that I found was to avoid SendInput altogether. Rather use the clipboard to copy the string inside, to then paste it on your screen. It works flawlessly, and is a billion times faster. Why would a person utilize SendInput in the first place? However, the actual question still is standing, why does SendInput behave so strangely? What is inside that string: %userInput% that causes my system to crash? How can I find out?
Related
I redefined all the keys on my numeric keypad to automate programming tasks, including 'cut, 'paste' and 'copy'. Everything works apart from this macro (paste):
;===== NumpadDot or NumpadDel paste
NumpadDot::
NumpadDel::
Send,^v
Return
Surprisingly this sends a control-v - Followed (slightly later) by a return/enter key. What causes AHK to send an extra keystroke and how do I prevent it? – None of my other macros appear to have this problem.
AHK probably interprets the Return as part of the Send command. Hotkeys automatically return, anyways, so you can just write:
NumpadDot::Send, ^v
NumpadDel::Send, ^v
...since it will 'Send' only the ^v and return to your script.
Using an AutoHotkey script I'd like to set the keyboard command Ctrl+D to delete the current line in any active Windows app.
How?
^d::Send {Home}{ShiftDown}{End}{Right}{ShiftUp}{Del}
Might not work in all edge cases, but passes some very basic testing in Notepad. =~)
HaveSpacesuit's answer works but after using it for a while I realized it deletes the active line and sometimes re-positions the spacing of the line below.
This led me to rethink his solution. Instead of going from the front of the line to the back, I tried going from back to front. This solved the re-positioning issue.
SendInput {End}
SendInput +{Home}
SendInput ^+{Left}
SendInput {Delete}
There is still a small problem though. If the cursor is on an empty line, with more empty lines above, then all empty lines get deleted.
I don't know a key combo to replace ^+{Left} that doesn't have this behavior so I had to write a more comprehensive solution.
^d:: DeleteCurrentLine()
DeleteCurrentLine() {
SendInput {End}
SendInput +{Home}
If get_SelectedText() = "" {
; On an empty line.
SendInput {Delete}
} Else {
SendInput ^+{Left}
SendInput {Delete}
}
}
get_SelectedText() {
; See if selection can be captured without using the clipboard.
WinActive("A")
ControlGetFocus ctrl
ControlGet selectedText, Selected,, %ctrl%
;If not, use the clipboard as a fallback.
If (selectedText = "") {
originalClipboard := ClipboardAll ; Store current clipboard.
Clipboard := ""
SendInput ^c
ClipWait .2
selectedText := ClipBoard
ClipBoard := originalClipboard
}
Return selectedText
}
As far as I can tell this produces no unexpected behaviour.
However, be careful if you're using a clipboard manager as this script uses the clipboard, if necessary, as an intermediary to get the selected text. This will impact clipboard manager history.
In case you run into problems where you need different behaviours for different programs, you can "duplicate" your ^d command for specific programs like this:
SetTitleMatchMode, 2 ; Makes the #IfWinActive name searching flexible
^d::Send {Home}{ShiftDown}{End}{Right}{ShiftUp}{Del} ; Generic response to ^d.
#IfWinActive, Gmail ; Gmail specific response
^d::Send {Home}{ShiftDown}{End}{Right}{ShiftUp}{Del} ; adapt this line for gmail
#IfWinActive ; End of Gmail's specific response to ^d
#IfWinActive, Excel ; Excel specific response.
^d::Send {Home}{ShiftDown}{End}{Right}{ShiftUp}{Del} ; adapt this line for Excel
#IfWinActive ; End of Excel's specific response to ^d
This way your ^d command will work differently in Excel and Gmail.
I have a simple way to solve the repositioning issue. Without using the clipboard.
The repositioning issue is due to the need to handle 2 separate cases.
if there's existing text in a line,
we want to select them all, and delete the text (backspace 1)
and backspace one more time to delete the empty line (backspace 2)
if it's a blank line,
we want to delete the empty line (backspace 1)
To cater for both of above cases, I introduced a dummy character.
This will make sure BOTH cases will act the same way.
So doing backspace 2 times, will result in the same transformation each time.
Simply,
; enable delete line shortcut
^d::
Send {Home}
Send {Shift Down}{End}{Shift Up}
Send d
Send {Backspace 2}
Send {down}
return
Disadvantage with this approach,
the dummy character "d" will appear when you undo. Not a bad tradeoff since I don't undo delete lines very often.
I'm trying to make filling some web-forms easier. Each form might include 100 times that tab would have to be pressed after typing a letter to be able to input the next letter to it's corresponding slot. I tried some examples, but ran in to problems when changing Windows language settings to Russian. Most of the time I will be inputting Russian letters, and if not, then just normal latin letters.
I tried following basic examples which worked for either one letter at a time or all (latin) letters at once.
#UseHook On
w::send ш{Tab}
Which outputs
ш(and one single TAB taking me to the next input)
So for some reason the characters are not correctly output from AHK.
This other example I found here and it works fine for any latin letter after a small modification:
https://autohotkey.com/board/topic/67948-detect-any-letter-key-press/
Loop 26
Hotkey, % Chr(A_Index+96),LatinLabel ;loop creating hotkeys for a-z
Return
LatinLabel:
Func(A_ThisHotkey)
Return
Func(var) {
#UseHook On
Send %var%{TAB}
}
I read that listening for all keypresses or actions would not be ideal, since this would also record mouse clicks and even movement.
So are there other alternatives googling didn't reveal to me?
Are you having problems with sending Unicode characters?
For the euro symbol I use either of:
SendInput {U+20AC}
PostMessage, 0x102, 8364, 1, Edit1, A ;WM_CHAR
The problem of ш becoming ш is due to the script file having been saved as UTF-8 without BOM. You just need to save the file as UTF-8 with BOM. AutoHotkey (as of v1.1.30.03) interprets files without a BOM as ANSI, because the default editor is Notepad, and Notepad (prior to Windows version 1903) defaults to ANSI.
The second script registers hotkeys a-z via the expression Chr(A_Index+96), which produces latin letters. Once registered, these hotkeys will activate when you press the corresponding virtual keys even if you change the keyboard layout. However, they will still send latin letters, because A_ThisHotkey is a-z.
The solution is to use the ~ hotkey modifier instead of sending the hotkey. In that case, pressing the key has whatever effect it should normally have, then the script sends Tab.
Loop 26
Hotkey % "~" Format("vk{:02x}", A_Index+64), AzKey
return
AzKey:
Send {Tab}
return
This registers hotkeys for the virtual keys vk41 - vk5A, which correspond to A - Z on layouts which contain those characters, but also work with other layouts. However, there may be some other keys which produce "letters" or other characters you want to watch for; in that case, just register additional hotkeys as needed.
Hotkey ~vkC0, AzKey
or stack the labels
vkC0::
AzKey:
I have a Autohotkey script that puts "D89dl" at the end of a sentence everytime I press Enter, but using it with a AutoCorrect script it doesn't work as it should. Let's say you type "dont", it then would look like this "don't" instead of "don't.". Something is blocking it but I'm not sure what it is, I've been trying for months now.
Here are the scripts:
enter::
send,D89dl{Enter}
Return
#Hotstring EndChars -()[]{}:;'"/\,.?!`n `t
::dont::don't
I would be VERY thankful if anyone of you helps me with this.
Overall, do you know any other way instead of Autohotkey that puts "D89dl" at the end of a sentence?
The easiest solution seems to be to use the :*: mode, which will trigger everytime the misspelled word is typed, without the need for Hotstring EndChars:
:*:dont::don't
Instead of using Enter, I suggest you use a special combination of keys that enter the string D89dl and then press Enter. Use a modifier like ctrl or alt and another key. The reasoning is that the key Enter has very important functionality and should not be changed. Pressing that special combination is appropriate, given the very special function it does.
It's a bit hacky, but it should do the job (given that by "end of sentence" you actually meant pressing "Enter"):
~enter::
Sleep, 100
SendInput, {BS}D89dl{Enter}
Return
#Hotstring EndChars -()[]{}:;'"/\,.?!`n `t
::dont::don't
How can write a hotkey (which works in any editor) to wrap currently selected text in ``
e.g double click "text", it becomes selected, then by pressing key for single `` it
is converted to text
Here is mix of pseudo code and actual code. Text within <> is what I'm not sure of
^<COMMAND FOR PRESSING ` KEY>::
KeyWait Control
<STORE CURRENTLY SELECTED TEXT IN MEMORY>
SendInput `<STORED SELECTED TEXT>'
return
Your approach is pretty good already. Try this:
$`::
clp_tmp := ClipboardAll
send ^c
currently_selected := Clipboard
stringReplace, currently_selected, currently_selected, `r,, All
Clipboard := clp_tmp
sendraw ``%A_Space%
sendraw %currently_selected%
sendraw ``%A_Space%
return
$ is needed because otherwise, sendraw `` would re-trigger this hotkey. The built-in variable clipboard / clipboardAll contains windows' clipboard. Also, you don't need any keywaits. ahk manages concurring modifiers from hotkey triggers by itself. I also suggest using sendraw which will not treat # as the win-button, + as Shift and so on.
script inserts new lines between each line if multiple lines are selected
Weird. When using msgBox, %currently_selected% instead of any send command, the line breaks are displayed correctly... there is obviously some strange formatting going on, I fixed it by simply removing all Carriage Returns (CR) (`r) from the string which does not change the selected text at all.
The given solution works for my keyboard which is German. This might be different for other keyboard layouts. For me, the %A_Space% in sendraw ``%A_Space% (at least in the second one) is needed, because if you state sendraw `` (a literal space character in the end), AHK will ignore it. You could also put all three sends in one line like
sendraw `` %currently_selected%``%A_Space%
Another solution might be
sendInput ````{BS}%currently_selected%````{BS}
or just simply
sendRaw `%currently_selected%`
Finally: If you wanted to make everything easier, make use of the #EscapeChar command and change the delimiter from ` to \ or sth. similar.