Getkey/Getvar Frequently Asked Questions

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

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

Last update: 18Feb2004

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 and later's CMD.EXE, %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, 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 later 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.

      Due to these inconsistencies, both utilities were modified to use -p.

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.

      The console input handler in the Win32 version does not support input
      redirection.

      I don't consider this to be a problem since these programs are
      intended to be interactive.

Q4.   Why are the DOS versions of getkey and getvar so slow on the Windows
      NT platform (NT/2000/XP/etc.)?

A4.   DOS programs are fully emulated and displayed inside a Win32 console
      session on the Windows NT platform. 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, the COMMAND.COM executable on the Windows NT platform
      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.   My command-line parameters aren't working properly.

A5.   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.

Q6.   How do I use quotes in a prompt?

A6.   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.

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

A7.   Setting an environment variable for the non-active environment
      programmatically is a fairly complex 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.

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

A8.   This is due to differences between the ASCII and ANSI character sets.
      Versions 7 and later of getvar 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.

Q9.   I can't enter a character at the getkey prompt when I use -l...

A9.   Check if you pressed the Insert key to put the line editor into
      insert mode. Getkey only allows one typed character. If you type a
      character and move underneath it, enable insert mode, then you will
      not be able to overtype it. Use the Del key, or move right and
      backspace.
