Input Stuffing

This topic is also discussed at: Keyboard: Sending Keystrokes.

Keystroke stuffing in DOS

There are some keystroke stuffing programs available for download.

One is a combination of a TSR called, which is bundled with 4DOS (which can now be obtained as freeware with distributed source code), in combination with the Keystack command built into the 4DOS program. Perhaps see these help topics: JP Software: Keys and Key Names, JP Softare: ASCII Codes and Key Names, JP Software: Keystack, and JP Software: Help: About Keystack. Information is also available for “Keys and Key Names”, and the two commands, in the help bundled with 4DOS (with some support built into 4DOS). Note for people using JP Software in other environments: the JP Software help: Activate describes a command that may be useful for bringing a window into the foreground.

These remaining resources are not meant to cover any particular order. (They were largely the ordre that I quickly found some.)

PC Magazine: Keyboard stuffing (including three pages later, after some advertisements)

Pascal source code for keyboard stuffing

More options exist: (Keyboard Buffer Stuffers) (Maybe also ?)


You may now get AutoHotkey from or The two websites used to be different ( history).

Karsten's question on, called “Where can I find a macro recorder for Autohotkey?”


Download AutoHotkey. Install it.

When installing, there is a screen titled “options”. The first couple of defaults are good, and recommended. (Those are: do “Install script compilter”, “Enable drag & drop” for the .ahk file extension, “Separate taskbar buttons”) The others are preference (and can be left to default).

After installing, when you run AutoHotkey, you may just find that AutoHotkey Help is run. The contents of that Autohotkey.chm file are also available online: AutoHotkey help: Welcome.

Specifically, AutoHotkey needs to find a sufficient script to be happy. (Otherwise, it may just show a help page, which properties identify as: “mk:@MSITStore:C:\Program%20Files\AutoHotkey\AutoHotkey.chm::/docs/Welcome.htm”. That page is also available online @ Autohotkey version 1 documentation: Welcome.)

You can solve this by simply providing a script in one of “the usual places” for AutoHotkey's script file. The script does need to have some content (and that content cannot just be a comment), or else the program will just exit quickly. Autohotkey documentation: Scripts: “Top of the Script (the Auto-execute Section)” provides guidelines on what can keep a script active. Some options include using the “#Persistent” command or just having a hotkey.

(The rest of this guide on AutoHotkey was thrown together rather quickly. Don't be afraid to check out the official Tutorials.) (Pieces of this guide were reviewed. Perhaps not all of it has been tested, at the time this note was written.)

Then, here are some commands:

return (script command)

This is important to know, so that you don't have multiple scripts run (one after another) when that isn't desired.

script labels/names
See: Tutorial section 21 (“Keys and their mysterious symbols”).
Send (script command)

This can be used to send keystrokes. There are some keys that are handled as special cases.

^The Ctrl key
!The Alt key (see: Alt keys)
^The the “Start” key
{Describe special handling (start)
{Describe special handling (end)
+The Shift key

It looks like mentioning “^C” is interpreted as Ctrl-Shift-C (not following the traditional standard, as described by control sequences and used by Unix, of treating Ctrl-C the same as Ctrl-c).

Using capital letters will imply use of the shift key, so using the + symbol may be unnecessary in many cases.

The { and } characters can often be used to describe other keys. For further details, see one or more of the documents hyperlinked in the “Documentation” section mentioned earlier.

SendInput (script command)
AutoHotkey documentation on the Send script command, subsection on using the “SendInput” script command

Like Send, but typically faster. (Possibly a bit less compatible with some programs.) Other such commands include the ControlSend (script command) (which is discussed in more detail later) and the SendPlay script command and the SendEvent script command.

Of those alternatives, the ControlSend (script command) is particularly worth knowing about, as it can help make sure keystrokes go to the intended program. (That is discussed further, later.) The other variations are probably worth checking into if there are problems, which may be more likely if sending larger amounts of characters. (For that matter, the SetKeyDelay command may also be helpful.)

Alter alternatives may be to simulate pasting text, rather than simulating keystrokes. Such commands include the Control script command and the ControlSetText script command (which may be affected by the SetControlDelay script command).

To re-cap: Plan on reading the following section about the ControlSend (script command). The other commands may be useful for people seeking optimal performance, or people encountering troubles, and there is some available material that can be read to learn more about them. That may or may not be worthwhile If the simple Send (script command) command works fine, perhaps the only other one that will be worth learning more about will be the the ControlSend script command.


One way to declare a variable, and initialize its value to blank, is:

sVarName :=;optional comment

To use the variables, in most cases the variable name gets surrounded by the derefencing character, which is typically the default value of a percent sign (although it can be changed, using the Delimiter command. AutoHotkey Delimiter documentation (at simply redirects to AutoHotkey documentation: Escape characters which mentions the Delimiter command.)

However, there may be times when the variable name doesn't get surrounded by copies of the delimiter character (which defaults to the percent sign). For instance, assigning variables doesn't use the percent sign, such as specifying a variable name for the Run, command's “OutputVarPID” parameter, or MouseGetPos.

MsgBox (script command)
msg can be used for prompting.

This can be used for output. This can also be used as an effective method of input. The following example is taken straight from the documentation, and shows effective usage of both a prompt, to gather some amount of input, and a simple output message.

This was heavily “inspired by”/“based on” an example at AutoHotkey documentation: the MsgBox command
MsgBoxType := 3 ; Yes/No/Cancel, per MsgBox, %MsgBoxType%,, Would you like to continue? (press Yes/No/Cancel)
IfMsgBox Yes
  MsgBox You pressed Yes.
else IfMsgBox No
  MsgBox You pressed No.
  MsgBox You pressed Cancel (or closed the child window).

See also: AutoHotkey Documentation: Else

Button names can be changed. (See:">Changing MsgBox's Names.)

Run, (script command)


sOutputVarPID :=
Run, Notepad,,UseErrorLevel,sOutputVarPID
WinWait ahk_pid %sOutputVarPID%
Mouse interaction
Mouse movement
^!c:: ; Initiated with Ctrl-Alt-c
  CoordMode, Mouse, Window ; (For sample purposes; default value)
  iMouseOldPosX := ; Right
  iMouseOldPosY := ; Down
  MouseGetPos, iMouseOldPosX, iMouseOldPosY
  MouseMove, iMouseOldPosX + 50, iMouseOldPosY + 150
  MsgBox "Moved"
  MouseMove, iMouseOldPosX, iMouseOldPosY

e.g., strings

e.g., saving mouse cursor position before moving

e.g., PID (from “RUN,” command)

AutoHotkey Tutorial: variables explains multiple ways to set a variable. That tutorial page notes that using “:=” “ is preferred by many due to its greater clarity”. When using that, variables are not needing to be surrounded by percent signs, but strings are required to be quoted. In contrast, using a “:=” “ for assignment can allow strings to be unquoted, and variable names are identified by being surrounded with percent signs.

Reserved variable names include: numbers (like %1%), Comspec, and numerous starting with “A_ (documented on the Autohotkey tutorial page about variables).

Other commands to be familiar with:

Reload (script command)

e.g., you may enjoy using these lines:

^!r:: ; Initiated with Ctrl-Alt-r

After saving the file, and telling AutoHotkey to reload, that will enable a more convenient way to tell Autohotkey to reload the script. That can be handy when making changes to the script.

WinActivate (script command)
WinWaitActivate (script command)
Sleep (script command)

This program can help get information, which can be useful for creating safer scripts that will try better to only send keystrokes to the desired application.

Go ahead and run the program. For some reason, its output fields tend to be blank until you make another program become the foreground application. Do that, and move the mouse around. Then the program will update.

ControlSend (script command)

AutoHotkey documentation: ControlSend. This is used for keyboard. “Unlike the Send command, mouse clicks cannot be sent by ControlSend. Use ControlClick for that.”

The following shows an example of how to run a command, and then send text into Wordpad's text entry field.

^!t:: ; Initiated with Ctrl-Alt-t

  iOutputVarPID :=
  sMyCmd := "Notepad.exe"
  ; The following can be learned using AU3_Spy.exe (bundled with AutoHotkey)
  sWordpadClassNNval := "RICHEDIT50W1" ; This is Wordpad's main text entry area
  sNotepadClassNNval := "Edit1" ; This is Notepad's main text entry area

  sClassNNval := %sNotepadClassNNval% ; Use Notepad's value
  sKeysToSend := "Hello World"
  Run, %sMyCmd%,,UseErrorLevel,iOutputVarPID
  if iOutputVarPID is not space
  { WinWait, ahk_pid %iOutputVarPID%
    Sleep 100
    SetKeyDelay, 10, 10
    ControlSend,%sClassNNval%,%sKeysToSend%,ahk_pid %iOutputVarPID%
    MsgBox,,"PID of started program is " + %iOutputVarPID%

^!m:: ; Initiated with Ctrl-Alt-m
  sOutputVar :=
  WinGet sOutputVar,PID,A
  MsgBox "PID of previously-active window " + %sOutputVar%
  MsgBox OutputVarControl is " + %OutputVarControl%


  • If you don't know the values for sClassNNval, you can remove the optional reference that is a part of the ControlSend command. (Using sClassNNval is not required, but may help to make sure text doesn't get sent to the wrong process.) Or, you could figure out the value of the ClassNN by using Windows Spy (AU3_Spy.exe bundled with AutoHotkey) or checking out the reported contents of iOutputVarControl.
  • Wordpad may not work as expected if you tried to use Write. This is because Write may just be a wrapper executable that ends up running something like "C:\Program Files\Windows NT\Accessories\Wordpad.exe" so the PID returned by the Run command would be the PID of the wrapper program (which is quickly terminated), not the PID of the surviving child process.
  • Besides that, Wordpad didn't seem to want to work well with ControlSend (nor Control nor ControlSetText, which are mentioned on the documentation for the ControlSend script command). When trying to send keystrokes, the only thing that did seem to cooperate decently at all was Send.
(HTML formatting/changes still needed) ; The part starting with ahk_pid is a "WinTitle".
; A "WinTitle" might be a title, but does not strictly need to
; be a title. If the "Wintitle" value starts with a recognized
; keyword, such as ahk_pid, then it can use another method to
; identify a window. For instance, using ahk_pid followed by a PID
; See help for AutoHotkey WinTitle for documentation
Input stuffing for Unix

GitHub: IronAHK. BSD 2-clause license.


There is a program named AutoKey which may be similar to AutoHotkey (which is for Microsoft Windows). However info on Autokey says Autokey is discontinued. The home page is at Google Code page for Autokey. Software is GPLv3. (Likley unrelated to Autokey for DOS, e.g. mentioned by's /msdos/keyboard-pre.html ??? For details on the Simtel archive, check out Microsoft OS code, and compatible/similar: section on downloadable software for MS-DOS and compatible/similar.

AutoHotkey forum post: software providing some functionality similar to AutoHotkey