Getkey/Getvar Frequently Asked Questions

(C) 2000-2002 by Bill Stewart (bstewart@iname.com)

This file is based partly on users' questions, and partly based on my own
investigation.

Last update: 28Jan2002

Q1.   I have placed a getkey or getvar command in a batch file, but when I
      double-click on the batch file, getkey or getvar doesn't run.

A1.   Any time a batch file calls an executable file, the executable file
      that it runs must be in a location where the batch file can find it.
      Generally, when a batch file is double-clicked from Windows Explorer,
      the current directory for that batch file as it runs is the same
      place that %COMSPEC% is started from. In other words, if you have a
      batch file with the following lines:

      @echo off
      rem display the current directory
      cd
      pause

      and you double-click it from the Windows Explorer, you will see batch
      file output that looks something like this:

      C:\WINNT\system32
      Press any key to continue . . .

      This is because the OS calls the COMSPEC variable to run the batch
      file, with the directory in the COMSPEC variable being the current
      directory.

      If you place the .EXE file in the same directory as the batch file,
      and that directory is not in the system path, the batch file is
      trying to run an executable file it can't find.

      There are two workarounds to this problem:

      1.  Copy the .EXE file to a directory in the system path.

      2.  Use the %0\..\ syntax to run the .EXE file from inside the batch
          file; e.g. %0\..\getkey instead of just getkey.

      The %0\..\ shorthand works because %0 expands to the batch file's
      file name, and \..\ means "the parent directory." Since %0 includes
      the file name itself, the \..\ "tricks" the command processor into
      thinking the file name is a directory, and thus points to the parent
      directory of a non-existent directory, which is the same directory
      that the batch file is started from.

      See Microsoft Knowledge Base article Q121387 for more information
      about how they use this syntax to deploy the SMS client software.

Q2.   Why was the -p command syntax changed between version 1 and 2?

A2.   On Windows 2000, %0 and anything appended to it is entirely enclosed
      in quotes (needed or not), to account for the possibility that that
      directory name the batch file is in (or the batch file's name itself)
      contains spaces. This confused the command-line parsing algorithm in
      version 1 of the utilities. In other words, if you create a batch
      file that contains the following lines:

      @echo off
      echo %0

      Suppose the file is called C:\BATCH\TEST.BAT. On all operating
      systems prior to Windows 2000, you will see the following output:

      C:\BATCH\TEST.BAT

      Under Windows 2000 and later, you will see:

      "C:\BATCH\TEST.BAT"

      Windows NT 4.0 appears to behave slightly differently, in that the
      string is only enclosed in quotes if it contains a space.

      If the batch file is on a network drive, Windows NT and 2000 use the
      UNC filename. In this case, quotes are needed if the share name,
      directory name, or batch file name contains spaces. Windows 9x
      appears to use a temporary drive letter and uses short filenames to
      reference the file.

      In any event, due to the fact that Windows 2000 always encloses %0 in
      quotes, both utilities were modified to require a -p parameter before
      specifying the desired prompt string.

Q3.   Input redirection doesn't seem to work.

A3.   The DOS versions of getkey and getvar rely on Turbo Pascal's readkey
      function. This function uses the system BIOS function (INT 10h) to
      read the keyboard, and this function call does not support input
      redirection. I didn't put forth the effort to call the DOS INT 21h
      function instead.

      In Win32, input redirection appears to hang the executable until you
      press Ctrl+C or Ctrl+Break. Keyboard input is handled by the
      ReadConsoleInput Win32 API function, so this may be related to how it
      handles the input.

      In any case, getting input redirection to work is not a high priority
      since these programs are intended to be interactive.

Q4.   Why are the DOS versions of getkey and getvar so slow on NT/2000?

A4.   DOS programs are fully emulated and displayed inside a Win32 console
      session on Windows NT/2000. This has an important ramification on how
      the program is presented on the screen in a console window.

      DOS programs can only handle certain screen dimensions. If NT detects
      that the DOS program attempts to write directly to the screen buffer,
      the OS will temporarily resize the console window to an acceptable
      size, imposing a considerable performance penalty.

      You can observe this behavior by creating a shortcut to CMD.EXE and
      defining an unusual (e.g. anything larger that 80x50) window size in
      the shortcut. Upon opening the shortcut, run getkeyd.exe and observe
      how the OS resizes the console window temporarily while getkeyd.exe
      is running. After you press Y or N to end the program, the OS will
      resize the window back to its previous dimensions.

      As a side note, NT/2000's COMMAND.COM executable is merely a "stub"
      program that passes nearly every command onto the underlying system
      command interpreter (usually CMD.EXE), and only includes a very small
      set of internal commands.

Q5.   Why is getkeyd.exe larger than getkey.exe?

A5.   The DOS version is compiled with numeric coprocessor emulation
      enabled, slightly enlarging the size of the .exe file.

Q6.   My command-line parameters aren't working properly.

A6.   If the problem is the prompt, make sure you are using -p. Versions 2
      and later require -p to explicitly specify the prompt string. (See
      Q2, above.)

      If the problem isn't the prompt, try explicitly separating the
      parameters with spaces, and for the parameters that need arguments,
      separate the parameter's argument from the parameter with a space. If
      the parameter's argument includes embedded spaces or tabs, enclose it
      in quotes.

Q7.   How do I use quotes in a prompt?

A7.   You can use either single quotes or double quotes when specifying a
      command-line parameter that contains spaces or tabs. If you want to
      include quotes as part of a parameter, use the other type to include
      them. For example:

      'Press "Enter" to continue...'

      It's currently not possible to include both types of quotes in a
      single string.

Q9.   Why doesn't getvar set the variable directly in the environment? Why
      generate the output batch file?

A9.   Setting an environment variable is a fairly complicated process. In
      DOS, it requires chasing PSP (program segment prefix) chains to the
      calling command processor. In Win32 it's much more complicated,
      because it's difficult to determine which program called the current
      one. In addition, I wanted getvar to work on all platforms: DOS,
      Win32 in Windows 9x/Me, and Win32 in Windows NT and later. The
      temporary batch file solution is the most portable, as it works in
      all of these environments.

Q10.  Why doesn't the Win32 console version of getvar correctly read in an
      environment variable that contains high-bit ASCII characters?

A10.  This is due to differences between the ASCII and ANSI character sets.
      Versions 7 and later of getkey now use the Win32 API function
      CharToOEMBuff to "translate" the variable's contents to its OEM
      equivalent string, which correctly handles most of the multinational
      and non-US currency characters. Other high-bit characters may not
      translate correctly. If this is a problem, always empty the variable
      before editing it; getvar always writes the output batch file
      correctly.
