Wizard's Apprentice

Main

Manual

Overview
Syntax
Installation
Using the Wizard's Apprentice
Building a wizard script
Command reference
Batch programming

Forum

Download



SourceForge.net Logo


*  The Wizard's Apprentice  *

Adding a face to your scripts

*Overview

The Wizard's Apprentice is a 32-bits Windows application (i.e. it works on Windows 95/98/Me/NT/2000/Xp) that lets you display a dialog box on the screen. It is meant to be executed from another program, like a script or a batch file, adding a way to ask the user questions in a friendly way.

The Wizard's Apprentice shows dialogs in the so-called 'wizard-style': large dialogs with a Back, a Next and a Cancel button, some explanatory text and one control where the user can choose something. You can choose from several different controls:

Text screen
No extra control, but an extra large text box, e.g. for a welcome text.
File contents
A box with a scroll bar on it, in which a file is displayed. Can be used to display a license text.
Edit field
An edit field where the user can type text.
Radio buttons
A set of up to ten radio buttons.
Checkboxes
A set of up to ten check boxes.
Listbox
Either a single-selection box, where you can select exactly one item, or a multiple-selection listbox, from which you can select zero or more items. Stand-in for radio buttons or checkboxes if you have more than ten.
Combo box
A combo box allows you to select an item from a list, or type it yourself.
File- or directory browser
An edit field with a Browse button next to it. Pressing the Browse button will either show an open file dialog, or a directory tree dialog.
Progress bar
A progress bar that stays on the screen while processing is done in the background. It can be updated to a percentage and then be closed.
Splash screen
A splash screen that can be shown while the program initialises. It can be closed whenever initialisation is completed.

Apart from that, the Wizard's Apprentice can also display a simple message box with the information, exclamation or stop icon, or with the question icon and an OK and a Cancel button.

With a little programming, you can use the Wizard's Apprentice to create wizards for installing things, starting programs, or automating simple tasks. The Wizard's Apprentice will provide an attractive user interface to your scripts.

This manual is divided into three parts: the first part is an elaborate tutorial on how to use the Wizard's Apprentice. It explains how to create a well-behaved wizard using the Wizard's Apprentice and the programming language of your choice. The second half is a reference manual for the Wizard's Apprentice, with a full explanation of all commands. The third part concentrates on batch programming: It shows useful techniques to get the most out of the Wizard's Apprentice in a batch environment.

*Syntax

wizapp MB <type>

type = INFORMATION | EXCLAMATION | STOP | QUESTION

or

wizapp [ NOBACK ] [ NOCANCEL ] [ FINISH ] <command> [ <options> ]

command = CB | CL | EB | FB | FT | LB | MB | RB
options are command specific options

-Environment variables

watitleSets the title of the dialog
watextSets the text of the dialog
wasigSets the bottom-left signature text of the dialog
waeolSets the End-of-Line character for watext
wainputSets the list for radiobuttons, checkboxes, listboxes and comboboxes
walistsepSets the list separator for wainput and other lists
wafileAlternatively sets the list for radiobuttons, checkboxes, listboxes and comboboxes
wabmpSets the picture for wizard-style dialogs
waicoSets the icon for wizard-style dialogs
walabelsSets the labels for the Back, Next, Finish and Browse button for wizard-style dialogs
wasoundSets the sound to play upon starting a wizard-style dialog
wabat Sets the batch/script file that is used to return selection information.
wascript Alias for wabat. If both are set, wabat wins.
waassign Template for the assignment expression. This is used to write wabat or wascript.
waoutputSets a control's default; contains the user's string after calling wabat
waoutnumSets a control's default; contains the user's index after calling wabat
waprefixSets the variables's prefix to something else than wa

-Error level returned

0The Next button or OK button was pressed
1The Back button was pressed
2The Cancel button was pressed
255An error ocurred

*Installation

The Wizard's Apprentice is meant to be called from another program. Only one file is needed, wizapp.exe. The only thing that is necessary is that the calling program can find it. This can be accomplished in three ways:

  • Make sure wizapp.exe sits in the same directory as the calling program. This is also very practical when you want to distribute a program that uses the Wizard's Apprentice. wizapp.exe can be called directly.
  • Make sure wizapp.exe resides in a directory in your PATH. That way it can always be found, regardless which directory the calling program is in.
  • Put wizapp.exe is on some drive where you can reach it from the computer the calling program runs on. You now need to call wizapp.exe using its full path name.

So, installing the Wizard's Apprentice is simply a matter of unpacking the distribution file into a directory of your choice. The distribution comes with a couple of other files:

wizapp.exe The program itself; the only file that needs to be redistributed.
wizapp.chm The program documentation.
license.txt The program license.
versions.txt The program's version history.
wizapp.xml Extra program information in PAD file format.
wainstall.bat An example program using the Wizard's Apprentice.

*Using the Wizard's Apprentice

Using the Wizard's Apprentice is a four-step process:

  1. Set the environment variables
  2. Call the program with the correct command line parameters
  3. Examine the errorlevel returned
  4. Examine the values returned

You tell the Wizard's Apprentice how it should look by setting a few environment variables; then you tell it what to do by passing it command line parameters. The Wizard's Apprentice, in turn, tells you what button the user pressed by returning an error level; it returns the user's input in a file written in your programming langage.

Let's look at a small example, written as a batch file:

  1.  set watitle=Important question
  2.  set watext=This is an important question.~Are you sure?~~Press OK if you are.~Press Cancel if you're not sure.
  3.  start /w wizapp MB QUES
  4.  if errorlevel 2 echo You're not sure.
  5.  if errorlevel 0 if not errorlevel 2 echo You're sure.

This batch file will show a message box on the screen that looks like this:

Screenshot of a messagebox

It will then print (on the console window you started the batch file from) either "You're not sure", if you pressed Cancel, or "You're sure" if you pressed OK.

Line 1 and 2 set two environment variables, watitle and watext, which contain the title and the text of the dialog box, respectively. watext contains some '~' characters; these denote line breaks.

The next line calls the application. This is done using the start command; start /w makes sure that the batch file waits until the application is finished. This is not necessary on Windows NT/2000/Xp, but on Windows 95/98/Me the batch file will go on running otherwise.

The application is called with two command line parameters: MB to display a message box, and QUES to indicate that it should have the question mark icon and two buttons, OK and Cancel.

Line 4 and 5 look at the errorlevel returned by the application. Errorlevel 2 means "Cancel is pressed", errorlevel 1 means "OK is pressed". Errorlevel 1 was left out here; it means "Back pressed" in wizard-style dialogs, but a message box does not have a Back button.

Note the way line 5 is written: if errorlevel 2 is true, that means that errorlevel 1 and errorlevel 0 are also true; all lower errorlevels are always true when an errorlevel is set. That's why it is explicitly stated that errorlevel 2 should not be true. This is the way it works in batch files; in another language, this is usually not necessary.

The same example could have been written in Perl:

  1.  $ENV{"watitle"}="Important question";
  2.  $ENV{"watext"}="This is an important question.~Are you sure?~~Press OK if you are.~Press Cancel if you're not sure.";
  3.  system("wizapp LB");
  4.  $errlevel = $? >> 8;
  5.  print("You're not sure.") if ($errlevel == 2);
  6.  print("You're sure.") if ($errlevel == 0);

Although the syntax is slightly different; the recipe is the same: set environment variables, start program, examine errorlevel. Line 4 is Perl's way of extracting the external program's exit code from the result of the call to system.

In this example, the user could only choose from two buttons, so the result could be returned in the exit code. For another example, let's take a look at the code for a typical language selection dialog:

  1.   set watitle=Choose a language
  2.   set watext=~~~~Choose a language you want the program to run in:
  3.   set wainput= ^&English; ^&French; ^&German; ^&Italian; ^&Spanish; ^&Dutch
  4.   set waoutnum=0
  5.   set wabmp=language.bmp
  6.   set wabat=%TEMP%\wabat.bat
  7.   start /w wizapp RB
  8.   if errorlevel 2 goto :cancel
  9.   if errorlevel 1 goto :previous
  10.   call %wabat%
  11.   if "%waoutnum%"=="0" echo Choice is English
  12.   if "%waoutnum%"=="1" echo Choice is French
  13.   if "%waoutnum%"=="2" echo Choice is German
  14.   if "%waoutnum%"=="3" echo Choice is Italian
  15.   if "%waoutnum%"=="4" echo Choice is Spanish
  16.   if "%waoutnum%"=="5" echo Choice is Dutch

watitle and watext are set just as in the previous example. watext again contains some '~' characters, which are converted to a line break in the output. This moves the line a little bit downwards; the text area in wizard-style dialogs is always the same size, so if you have only little text it looks nicer that way.

In line 3, wainput is set, which contains the choices the user will have. In every choice, you can precede a character with an '&' character; this character will be underlined in the dialog box and can be used as a hotkey for that choice. In a batch file, '&' characters have a special meaning; that's why they must be escaped using the '^' character.

Line 4 sets the environment variable waoutnum. It has two functions; when you set it before the dialog is displayed, it sets the default choice in the dialog; afterwards, it will contain the choice the user made. Here we set it to '0', which denotes the first choice in the list, in this case English.

Line 5 sets the picture of the dialog. It is a drawing that appears on the left side in the dialog. It should be a .bmp file. The picture is not resized, so you should make sure it more or less fits the dialog. If you do not specify a picture you will get the default picture.

Line 6 sets the variable wabat, which contains the name of the batch file used to return values. The batch file is called in line 10, directly after the Wizard's Apprentice was executed. This batch file will contain lines like this:

    set waoutput= ... something...
    set waoutnum= ... something else...

If you execute this batch file from your own, the variables waoutput and waoutnum will be set.

(This is the only way to set variables in the batch file's environment; the Wizard's Apprentice cannot directly change variables in the batch file's environment, as it only receives a copy of that environment when it is executed. Therefore it creates another batch file, which you can call to retrieve the results of the dialog.)

If you do not set wabat to a valid batch file name, you will not be able to find out what the user answered. %TEMP%\wabat.bat probably is a safe name, but the choice is yours.

Here's the dialog that will be displayed when you run this batch file:

Screenshot of a language 
    selection dialog

Line 8 and 9 examine the errorlevel set by the dialog. In this case, we do have a Back button, so we go to another place in the batch file when that button is pressed (the label :previous in this case.) Since the lines after a goto are not reached, we do not need to use the if errorlevel if not errorlevel construct here.

Line 11 to 16 evaluate the value of the environment variable waoutnum to see which choice the user made. I this case, the choice is only printed to the screen.

This example could also be written in other languages. Let's take a look at a version written in PHP:

  1.   putenv("watitle=Choose a language");
  2.   putenv("watext=~~~~Choose a language you want the program to run in:");
  3.   putenv("wainput= &English; &French; &German; &Italian; &Spanish; &Dutch");
  4.   putenv("waoutnum=0");
  5.   putenv("wabmp=language.bmp");
  6.   putenv("wascript=wascript.php");
  7.   putenv("waassign=<?php \$%1='%2'; ?>");
  8.   system("wizapp.exe RB", $errlevel);
  9.   if ($errlevel == 2) cancel();
  10.   if ($errlevel == 1) {
  11.       $page--;
  12.       continue;
  13.   }
  14.   include("wascript.php");
  15.   if ($waoutnum == "0") echo "Choice is English";
  16.   if ($waoutnum == "1") echo "Choice is French";
  17.   if ($waoutnum == "2") echo "Choice is German";
  18.   if ($waoutnum == "3") echo "Choice is Italian";
  19.   if ($waoutnum == "4") echo "Choice is Spanish";
  20.   if ($waoutnum == "5") echo "Choice is Dutch";

The recipe is very similar to the batch file discussed earlier. There are only a few things worth mentioning.

Line 7 and line 14 work together in getting the user's response back into the PHP program. Although it would be possible to read in a batch file and extract the information from it, there is an easier way to do this: just tell the Wizard's Apprentice in what format it should return the information. Here, the environment variable waassign is set explicitly with the value <?php $%1='%2'; ?>. (In the code, the '$' and the '"' are escaped with a backslash character.) What does this mean?

The Wizard's Apprentice will substitute '%1' with the name of a variable, and '%2' with a value. Thus, when it wants to tell you that waoutput should be 5, it will write the following line to wascript.php:

    <?php $waoutnum='5'; ?>

Only %1 and %2 are replaced, the rest of the template is copied verbatim. This is valid PHP, and can be included into your PHP program, which is done in line 14.

Note that we use the variable wascript here instead of wabat. This has no special meaning; it is just that the word 'bat' is a bit strange in a context other than batch files. Therefore, you can use wascript instead; it has exactly the same meaning. If both are set, the value for wabat will be used.

The logic in lines 8-12 handles the buttons the user pressed. It is assumed here that a function cancel() exists, which will exit if necessary. Furthermore, line 11 and 12 could be a method to let the user navigate through a wizard. More on this later.

In Perl, you would use the $ENV{...} = ...; syntax, but the rest of this example would be almost identical. However, here's how to set the correct template for Perl:

    $ENV{"waassign"} = "\$\%1='\%2';";

It will write a file with lines like this:

    $waoutnum='0';

The file can be read in like this:

    do "wascript.pl";

In the first example for the language dialog, the batch file, the waassign template was not set. This wasn't necessary, as the Wizard Apprentice will assume batch syntax as default when waassign is empty. To set it explicitly, you would need:

    set waassign=set %%1=%%2

The double '%' signs are to avoid confusion with command line parameters.

In a typical wizard, you would probably have more than one wizard page. The following section will explain how you can create a wizard that behaves as you would expect.

*Building a wizard script

The previous section showed the basic use of the Wizard's Apprentice. In this section, it is shown how to create a wizard-like application.

A wizard usually starts with a welcome screen, telling the user what will follow. It then asks the user to make choices, allowing him or her to go back and forth to review these choices, until in the end the actual work is done. If at any moment the user presses the Cancel button, a confirmation dialog is shown, where the user can choose to really quit or to go on where he or she left. It is of course possible that the answer to a question changes the questions asked afterwards; if the answer to "Do you want to make a backup of the old files?" is "No", you don't have to ask in which directory to make the backup.

In this section, it is explained how a wizard should behave. Some examples in different script languages are used. It is relatively difficult to make a wizard in batch language. Therefore, there is a tutorial on batch programming in part three.

-Basic outline of a wizard script

When creating a wizard, you should keep in mind that the user expects to be able to go back and forth between pages, reviewing his or her choices, until finally he or she is satisfied with it and hits the Finish button. Usually, the title and the picture of the wizard pages don't change in between. A basic outline for a wizard script should be as follows:

Set variables you only need to set once
Usually, the variables wabmp, watitle, wascript, and probably others only need to be set once. Why no do it right in the beginning?
Clear all other variables
It is always possible that a variable was set by a previous program, or has a totally different meaning for a different program. To avoid surprises, clear them all.
Do other initialisations
Any stuff you own script needs.
Wizard pages
The actual pages of your wizard.
Do the work
After all information is gathered from the wizard pages, and the user pressed "Finish", use that information to do the actual work.
Clean up
Clear all variables you used. That way no strange environment variables are left behind. Delete all files your created (like the one wascript points to.)

-The welcome screen and the finish page

Usually, the first page of a wizard contains a welcome text, outlining what is going to happen next. However, it is very well possible that the first screen contains a control, and asks a first question already. The only thing that makes the first page special is that it doesn't have a Back button.

This is achieved in the Wizard's Apprentice with the NOBACK parameter. If you call the Wizard's Apprentice as follows:

    wizapp.exe NOBACK TB

it will show a textbox (because of the TB parameter), but no Back button.

Similarly, if you call the Wizard's apprentice like this:

    wizapp.exe FINISH TB

it will use a Finish button instead of a Next button. The only difference between a Finish button and a Next button is the label; the Wizard's Apprentice will return errorlevel 0, just as if the Next button was pressed.

You can also have both:

    wizapp.exe NOBACK FINISH CL

This is a very short wizard, asking only one question and finishing immediately.

Although it is not recommended, sometimes it may be necessary to disallow the user to cancel a dialog. In that case, you can use the NOCANCEL parameter:

    wizapp.exe NOCANCEL TB

A textbox will be shown, but the Cancel button will be disabled. Needless to say, you can combine the NOCANCEL parameter with the other ones. The order in which you specify the global parameters is not important; the following two calls have exactly the same effect, a dialog in which only the Finish button can be used:

    wizapp.exe NOBACK FINISH NOCANCEL TB
    wizapp.exe NOCANCEL NOBACK FINISH TB

-Going back and forth

If you have more than one page in your wizard, you must make sure that the Back button and the Next button work as intended. The trick to accomplish this is to look at the errorlevel that is returned.

0The Next button or OK button was pressed
1The Back button was pressed
2The Cancel button was pressed
255An error ocurred

In your script, you should examine the errorlevel returned by the Wizard's Apprentice and decide what to do. A relatively easy construct that can be used in most languages is this:

    page = 1
    while (not done)
        if page == 1
            show page 1
            if errorlevel 0 page = page + 1
            if errorlevel 2 cancel()
        else if page == 2
            show page 2
            if errorlevel 0 page = page + 1
            if errorlevel 1 page = page - 1
            if errorlevel 2 cancel()
        end if
        ... Etc. for all pages
    end while
    ... Rest of program

This so-called "master loop" makes it easy to go back and forth through the pages. The only thing you have to do in the block for each page is set the page variable right for the next step. A slight variation of a block allows you to skip a page:

        ...
        else if page == 2
            show page 2
            if errorlevel 0
                call wascript
                if waoutnum == 2
                    page = page + 1
                else
                    page = page + 2
            if errorlevel 1 page = page - 1
            if errorlevel 2 cancel()
            ...

Here, the choice the user made is examined (by calling wascript in whatever way and looking at waoutnum,) and used to decide whether to skip a page or not.

In a batch file, it's probably best to use gotos. More in this in part three.

-Cancel confirmation

To handle the pressing of the Cancel button, it is common to display a confirmation dialog. That could be done using wizapp MB QUES. This will show a messagebox with two buttons, an OK button and a Cancel button. You could show a messagebox like this:

The error level returned from the messagebox is exactly the same as from the wizard-style dialog boxes, except that the messagebox doesn't have a back button.

In the previous examples, it was assumed a function existed called cancel(); it could be implemented like this:

    function cancel()
        set text to "Are you sure?"
        wizapp MB QUES
        if errorlevel 0 exit
        if errorlevel 2 return

In a batch file, this process is again a bit more complicated. See part 3 for more on batch files.

*Command reference

This section contains a complete reference of all commands the Wizard's Apprentice knows, in alphabetical order. For each command, it is explained what environment variables it uses and what it does.

-General reference

Global options

You can specify global options before the command on the command line.

NOBACKDo not display a Back button on a wizard-style dialog.
NOCANCELDisable the Cancel button on a wizard-style dialog.
FINISHDisplay a Finish button on a wizard-style dialog, instead of a Next button.

Command line abbreviations

Every option to the Wizard's Apprentice, both global options and command specific options, can be abbreviated by leaving out letters, as long as the result is unambiguous. e.g.

    start /w wizapp NOB LB S
    start /w wizapp MB INFO

is the same as

    start /w wizapp NOBACK LB SINGLE
    start /w wizapp MB INFORMATION

It is recommended not to abbreviate too much; MULTI instead of MULTIPLE is understandable, but

    start /w wizapp NOC F FB F

is not so easy to grok at first sight.

Errorlevel returned

For each command, the Wizard's Apprentice returns the same errorlevel:

0The Next button or OK button was pressed.
1The Back button was pressed.
2The Cancel button was pressed.
255An error ocurred.

If the NOBACK option was used, errorlevel 1 will never be returned. Likewise, errorlevel 2 will not be returned if NOCANCEL was used. If the FINISH option was used, and the Finish button was pressed, the Wizard's Apprentice returns errorlevel 0, just as if the Next button was pressed.

The waico variable

Just as you can set the sidebar bitmap of the wizard style dialogs, you can set the icon of these dialogs using the waico variable. It should contain the filename of an .ico file which will be used as the icon for the application. If you do not specify an icon, the default icon will be used.

waico Sets the icon for wizard-style dialogs

The wasig variable

In the bottom-left corner of the wizard-style dialogs the name and version number of the application is shown. You can replace this text with one of your own by setting the wasig variable. You should make sure the text is not too long, or it will be truncated.

wasig Sets the bottom-left signature text of the dialog

The wasound variable

It is possible to play a sound at the moment a wizard-style dialog appears. This is done by setting the wasound variable to point to a .wav file. If the file does not exist, or the sound device is busy, this variable will be ignored.

wasound Sets the sound to play upon starting a wizard-style dialog

wainput and wafile

Usually you set the contents of a listbox, checklist, radiobutton set or combobox using the wainput variable, but if the wafile variable is set, the contents of the file it points to are used. The items in this file are not separated by the list separator; instead, every line in the file denotes one item.

The returned values for waoutput and waoutnum will still use list separators if they contain multiple values, e.g. from a checklist.

Similarly, you usually use wafile for a filetext box, but you can also use wainput for that if you have only little text. In that case, the list separator is just displayed, but the End-of-line character is used to split the input into lines.

If you set both wafile and wainput, wafile wins; that means the contents of the file are used, and the contents of wainput are discarded.

Continuation variables: watext2 and others

When the contents of an environment variable become large, it is possible to continue it in a second varable. This comes in handy in at least two case:

  • On Windows 95/98/Me, the maximum command line size is 128 characters. This limit is also present within a batch file. If you need a text larger than that, you can split it into two commands.
  • When you have part that is always the same and a part that varies among pages, you don't have to repeat the stationary part.

Continuation works as follows. Let's take watext as an example. If watext is set, the Wizard's Apprentice will read it, and will then read the the variable watext2 and concatenates its value to that of watext. It then concatenates watext3, watext4 and so on, until it finds an empty one.

Here's an example with a long text:

    set watext=Welcome to the Wizard's Apprentice setup
    set watext2=~~This program will install the Wizard's Apprentice.
    set watext3=~~Wizard's Apprentice adds a user interface to your scripts:
    set watext4=~~* Use message boxes for simple questions
    set watext5=~* Tickboxes and listboxes for complicated questions
    set watext6=~* Display files, e.g. licenses
    set watext7=~* Configurable buttons, picture and title
    set watext8=~* File and directory box with Browse button
    set watext9=~* Show splash screens, progress bars and play sounds
    set watext10=~* Sample batch files and comprehensive manual
    set watext11=~~... and the Wizard's Apprentice is free!
    set watext12=~~Press the [Next] button to start the installation.

Each line is less than 128 characters, but the final text is much longer. Don't forget to clear those variables before you go on with the next step.

Variable continutation works with the following variables:

    watext
    watitle
    wasig
    wainput
    waoutput
    waoutnum
Be careful when using it with the last two: the script that returns the user input will not use variable continuation, so if the value for waoutnum becomes too large you will not be able to retreive it.

Another example shows the use of variable continuation for specifying a fixed and a variable part. Imagine a 3 page wizard that shows the current page number in the title bar. It could be written as follows (batch syntax):

    set watitle=My Wizard 1.0  -
    ...
    :page1
    set watitle2=  page 1/3
    ...
    
    :page2
    set watitle2=  page 1/3
    ...
    
    :page3
    set watitle2=  page 1/3
    ...
    

This will display the title of the wizard like "My Wizard 1.0  -  page 1/3", etc. but you don't have to type the "My Wizard" part three times.

The walabels variable

The labels for the Back, Next, Finish and Browse buttons in wizard-style dialogs are normally "Back", "Next", "Finish" and "Browse" respectively. The walabels variable can be set to a list of other names for the buttons, by specifying the names in this order: Back, Next, Finish, Browse.

walabels Sets the labels for the Back, Next, Finish and Browse button for wizard-style dialogs

If you leave a label empty, the Wizard's Apprentice will use the default label, so you can change only the label of the Next button as follows (batch syntax):

    set walabels=;I accept

You can set hotkeys for the buttons by prefixing a letter in the button label with an '&' character.

Note on batch files:

If you use Windows NT/2000/Xp, you have to escape the '&' character with a '^' character in your batch file. E.g.

    set walabels=Vo^&rige;^&Volgende;^&Einde;^&Blader

sets the labels in Dutch, with 'R', 'V', 'E' and 'B' as hotkeys, respectively.

On Windows 95/98/Me you should not escape the '&' characters. If you want to write a batch file that works on both Windows 95/98/Me and NT/2000/Xp, you can use the following test:

    if "%OS%"=="Windows_NT" set walabels=;;^&Install;
    if not "%OS%"=="Windows_NT" set walabels=;;&Install;

the OS variable is also set to Windows_NT on Windows 2000 and Windows Xp.

The waeol variable

watext and wainput specify the contents of your dialog. You can use the character '~' to put a line break in your contents. If you want to display a '~' character in your contents, you need another character to denote a line break. The line break character can be specified by setting the waeol variable.

waeol Sets the End-of-Line character for watext

The walistsep variable

The wainput variable is used to set the contents of listboxes, radiobuttons, checklists and comboboxes. The default separator between list items is the character ';'. This means you cannot have a ';' character in your list items. You can set a different list separator by specifying the walistsep variable.

walistsep Sets the list separator for wainput and other lists

Note that this character will be used in all lists; this includes the lists that are returned in waoutput and waoutnum, and the list of button labels you specify for walabels.

The waprefix variable

The standard names for the environment variables used by the Wizard's Apprentice all start with wa. It is possible to change this prefix by setting the waprefix variable.

waprefix Sets the variables's prefix to something else than wa

E.g. if you have environment variables with the same names as Wizard's Apprentice variables that you don't want to change, you can use the following code (batch syntax):

    set waprefix=wizapp
    set wizapptext=Are you sure?
    start /w wizapp MB QUESTION

This way, you don't have to use or change the variable watext.

Note that the variable waprefix itself never changes; it always has the prefix wa. If you have another variable of the same name, you should store its value if you want to keep it, by assigning its value to another, temporary environment variable.

Note that the size of the prefix should not be more than 64 characters. If the value of waprefix is longer than that, it will be truncated.

Command overview

CommandMeaningOptions
CBCombobox (edit field with drop down list)
CLChecklist (up to ten checkboxes)
EBEditbox (edit field for text or password)[ PLAIN | HIDDEN ]
FBFilebrowser (or folder browser)[ FILE | DIR ]
FTFiletext (contents of a file)
LBListbox (list of selectable items)[ SINGLE | MULTIPLE ]
MBMessagebox[ INFORMATION | EXCLAMATION | STOP | QUESTION ]
PBProgress bar[ OPEN | UPDATE <percentage> | CLOSE]
RBRadiobuttons (up to ten mutual exclusive choices)
SPLASHSplash screen[ OPEN | UPDATE | CLOSE ]
TBTextbox (a dialog with only text in it)

-CB -- Combobox

Syntax

wizapp CB

Variables used

watitle Sets the title of the dialog box.
wasig Sets the bottom-left signature text of the dialog
watext Sets the text of the dialog box.
wabmp Sets the sidebar picture of the dialog box.
waico Sets the icon for wizard-style dialogs
wasound Sets the sound to play upon starting a wizard-style dialog
wainput Sets the contents of the listbox part of the combobox.
wafile Alternatively sets the contents of the listbox part of the combobox.
wabat Sets the batch/script file that is used to return selection information.
wascript Alias for wabat. If both are set, wabat wins.
waassign Template for the assignment expression. This is used to write wabat or wascript.
waoutput In: Sets the initial (default) text of the editbox part of the combobox;
Out: Returns the item selected or typed by the user.
waoutnum In: Sets the item selected by default in the listbox part of the combobox, which is copied into the editbox part;
Out: Returns the item selected by the user, or the highest possible index + 1 if the user typed something.

Description

This command shows a combobox in a wizard-style dialog on the screen. A combobox is a combination of an editbox and a listbox; the user can type items, or select items from the list.

Screenshot of a dialog with a combobox

The listbox of the combobox can be filled in two ways: by setting wainput or wafile. wainput contains a list of items, separated by the list separator character. wafile is the name of a file in which each line is added as an item to the list. If you set both, wafile gets preference and the contents of wainput are not used.

You can initialise the combobox in two ways: either set waoutnum to a zero-based index in the list, or set waoutput to an item to appear in the editbox. If you do both, the latter wins.

To retrieve the selection the user made you have to set the name of the batch/script file before displaying the dialog, and call that batch/script file afterwards. You can then examine the value of waoutput and waoutnum. waoutput contains an item from wainput, or the text that the user typed; waoutnum contains a zero-based index in the list, or the highest possible index + 1 if the user typed something that is not in the list.

Note: If you do not initialise the combobox, and the user presses Next without doing anything else, waoutput will be empty, and waoutnum will be the highest possible index + 1.

-CL -- Checklist

Syntax

wizapp CL

Variables used

watitle Sets the title of the dialog box.
wasig Sets the bottom-left signature text of the dialog
watext Sets the text of the dialog box.
wabmp Sets the sidebar picture of the dialog box.
waico Sets the icon for wizard-style dialogs
wasound Sets the sound to play upon starting a wizard-style dialog
wainput Sets the labels of the checkboxes. Only the first 10 items are used.
wafile Alternatively sets the labels of the checkboxes. Only the first 10 items are used.
wabat Sets the batch/script file that is used to return selection information.
wascript Alias for wabat. If both are set, wabat wins.
waassign Template for the assignment expression. This is used to write wabat or wascript.
waoutput In: Sets the items checked by default in the checkboxes;
Out: Returns the items checked by the user.
waoutnum In: Sets the items checked by default in the checkboxes;
Out: Returns the items checked by the user.

Description

This command shows a set of maximum ten checkboxes in a wizard-style dialog on the screen. The user can check zero or more items in the set.

Screenshot of a dialog with a checklist

The labels of the checkboxes can be set in two ways: by setting wainput or wafile. wainput contains a list of labels, separated by the list separator character. wafile is the name of a file in which each line is added as a label to the list. If you set both, wafile gets preference and the contents of wainput are not used.

You can initialise the checklist in two ways: either set waoutnum to a list of zero-based indices in wainput, or set waoutput to a list of items from wainput. All items appearing in any of those lists will be checked.

To retrieve the selection the user made you have to set the name of the batch/script file before displaying the dialog, and call that batch/script file afterwards. You can then examine the value of waoutput and waoutnum.

waoutput contains a set of items from wainput; waoutnum contains a set of zero-based indices in the list. Here's a possible way to extract items from the list in a batch file:

    for %%c in (0 1 2 3 4 5 6 7 8 9) do set chk%%c=
    for %%c in (%waoutnum%) do set chk%%c=1
    if "%chk0%"=="1" echo Item 0 was checked
    if "%chk1%"=="1" echo Item 1 was checked
    ...
    if "%chk9%"=="1" echo Item 9 was checked

In a PHP program you could use explode(); in Perl you could use split().

You can never have more than 10 checkboxes. If you have more items to choose from, you can use a multiple selection listbox instead.

-EB -- Editbox

Syntax

wizapp EB
wizapp EB PLAIN
wizapp EB HIDDEN

Variables used

watitle Sets the title of the dialog box.
wasig Sets the bottom-left signature text of the dialog
watext Sets the text of the dialog box.
wabmp Sets the sidebar picture of the dialog box.
waico Sets the icon for wizard-style dialogs
wasound Sets the sound to play upon starting a wizard-style dialog
wabat Sets the batch/script file that is used to return selection information.
wascript Alias for wabat. If both are set, wabat wins.
waassign Template for the assignment expression. This is used to write wabat or wascript.
waoutput In: Sets the initial (default) value filled in in the editbox;
Out: Returns the text typed by the user.

Options

PLAIN Everything the user types is visible in the editbox.
HIDDEN Everything the user types is hidden; *'s are shown instead.
When no option is provided, PLAIN is used.

Description

This command shows an editbox in a wizard-style dialog on the screen. The user can type a text in the edit box.

Screenshot of a dialog with an editbox

You can initialise the editbox by setting waoutput beforehand.

To retrieve the selection the user made you have to set the name of the batch/script file before displaying the dialog, and call that batch/script file afterwards. waoutput then contains the text typed by the user.

Depending on the option used, the text is hidden (like passwords); if no option is given, or PLAIN is used, the text is visible, if HIDDEN is used, stars (*) are displayed for each character the user types.

Screenshot of a dialog with an editbox

NOTE: This is a display option only, and does not provide any security. Anyone can change your script and show or store passwords typed. Do not use plain script files to let users enter sensitive information!

-FB -- Filebrowser

Syntax

wizapp FB
wizapp FB FILE
wizapp FB DIR

Variables used

watitle Sets the title of the dialog box.
wasig Sets the bottom-left signature text of the dialog
watext Sets the text of the dialog box.
wabmp Sets the sidebar picture of the dialog box.
waico Sets the icon for wizard-style dialogs
wasound Sets the sound to play upon starting a wizard-style dialog
wainput Sets the filter string that is used in the open file dialog
wabat Sets the batch/script file that is used to return selection information.
wascript Alias for wabat. If both are set, wabat wins.
waassign Template for the assignment expression. This is used to write wabat or wascript.
waoutput In: Sets the initial (default) value for the editbox;
Out: Returns the file or directory selected by the user.

Options

FILE Show a file open dialog when the user presses the Browse button.
DIR Show a browse folder dialog when the user presses the Browse button.
When no option is provided, FILE is used.

Description

This command shows an editbox with a Browse button next to it in a wizard-style dialog on the screen.

Screenshot of a dialog with a filebrowser

When the user presses the Browse button, a file open dialog or a browse folder dialog is shown. Which dialog is shown depends on the option used. If the option is FILE, an open file dialog is shown:

Screenshot of a file open dialog

wainput can be used to specify filter strings. Filter strings are used to specify the file types you want to show in the open file dialog (Files of type: in the drop down list on the bottom.) This often contains items like Text files (*.txt) and All files (*.*).

Filter strings are specifies in pairs; the first part is the part that the user sees, e.g. Text files (*.txt). The second part is a wildcard expression specifying that file type, e.g. *.txt. wainput is a list of such pairs, separated by the list separator (normally ";".) Here's an example:

  1.  set wainput=Text files (*.txt);*.txt;All files (*.*);*.*

Note that the expression in brackets is for display only. After the semicolon follows the real wildcard expression.

It is possible to have multiple wildcard expressions for one file type, like *.htm and *.html. For that, you have to separate them with a semicolon. Since this also is the default list separator for the Wizard's Apprentice, you will have to change this first. Here's an example: (batch syntax)

  1.  set walistsep=,
  2.  set wainput=All batch files (*.cmd; *.bat),*.cmd;*.bat,CMD files (*.cmd),*.cmd,BAT files (*.bat),*.bat,All files (*.*),*.*
  3.  start /w wizapp FB file
  4.  set walistsep=

This will show an open file dialog with four file types: "All batch files (*.cmd; *.bat)", "CMD files (*.cmd)", "BAT files (*.bat)" and "All files (*.*)".

If the DIR option is used, a folder browser is shown.

Screenshot of a folder browse dialog

wainput is ignored when the DIR option is used.

When the user chooses a file or directory, it is filled in in the editbox.

You can initialise the editbox of the filebrowser by setting waoutput beforehand.

To retrieve the selection the user made you have to set the name of the batch/script file before displaying the dialog, and call that batch/script file afterwards. You can then examine the value of waoutput.

Note that waoutput does not necessarily contain a valid file name, as it is also possible that the user typed something into the editbox without using the Browse button. In the section Advanced batch techniques some ways are explained to determine whether a filename or a directory name is valid.

-FT -- Filetext

Syntax

wizapp FT

Variables used

watitle Sets the title of the dialog box.
wasig Sets the bottom-left signature text of the dialog
watext Sets the text of the dialog box.
wafile Sets the contents of the filebox.
wainput Alternatively sets the contents of the filebox.
wabmp Sets the sidebar picture of the dialog box.
waico Sets the icon for wizard-style dialogs
wasound Sets the sound to play upon starting a wizard-style dialog

Description

This command shows a textbox in a wizard-style dialog on the screen. The textbox has a scrollbar on the right side, and contains the contents of the file specified in wafile.

If you have only little text, you can set wainput instead of wafile; then wainput is displayed. The End-of-line character can be used to specify line breaks in wainput.

Screenshot of a dialog with a textfile

This command can be used e.g. to display a license text.

-LB -- Listbox

Syntax

wizapp LB
wizapp LB SINGLE
wizapp LB MULTIPLE

Variables used

watitle Sets the title of the dialog box.
wasig Sets the bottom-left signature text of the dialog
watext Sets the text of the dialog box.
wabmp Sets the sidebar picture of the dialog box.
waico Sets the icon for wizard-style dialogs
wasound Sets the sound to play upon starting a wizard-style dialog
wainput Sets the contents of the listbox.
wafile Alternatively sets the contents of the listbox.
wabat Sets the batch/script file that is used to return selection information.
wascript Alias for wabat. If both are set, wabat wins.
waassign Template for the assignment expression. This is used to write wabat or wascript.
waoutput In: Sets the items selected by default in the listbox;
Out: Returns the items selected by the user.
waoutnum In: Sets the items selected by default in the listbox;
Out: Returns the items selected by the user.

Options

SINGLE Show a single-selection listbox, i.e. a listbox in which the user can select exactly 1 item.
MULTIPLE Show a multiple-selection listbox; the user can select zero or more items.
When no option is provided, SINGLE is used.

Description

This command shows a listbox in a wizard-style dialog on the screen. You can use a listbox if you have too many items for checkboxes or radiobuttons. A single selection listbox always has one item selected, and the user can move the selection.

Screenshot of a dialog with a single-selection listbox

In a multiple-selection listbox the user can use the Shift-key while clicking to select a range of items; the Control-key while clicking to add an item to the selection; or drag with the mouse to select a range of items.

Screenshot of a dialog with a multiple-selection listbox

The contents of the listbox can be set in two ways: by setting wainput or wafile. wainput contains a list of items, separated by the list separator character. wafile is the name of a file in which each line is added as an item to the list. If you set both, wafile gets preference and the contents of wainput are not used.

You can initialise the listbox in two ways: either set waoutnum to a list of zero-based indices in the list, or set waoutput to a list of listitems. All items appearing in any of those lists will be selected. In a single-selection listbox, only one item should be selected; if you accidently specify more, only the last item will be selected.

To retrieve the selection the user made you have to set the name of the batch/script file before displaying the dialog, and call that batch/script file afterwards. You can then examine the value of waoutput and waoutnum.

waoutput contains a list of items from wainput; waoutnum contains a list of zero-based indices in the list. Here's a possible way to extract items from the list:

    for %%s in (0 1 2 3 4 5 6 7 8 9) do set sel%%s=
    for %%s in (%waoutnum%) do set sel%%s=1
    if "%sel0"=="1" echo Item 0 was selected
    if "%sel1"=="1" echo Item 1 was selected
    ...
    if "%sel9"=="1" echo Item 9 was selected

This example works for a listbox with 10 items, although listbox can contain an arbitrary number of items.

In a PHP program you could use explode(); in Perl you could use split().

If you have less than 10 items, you can use radiobuttons instead of a single selection listbox, or a checklist instead of a multiple selection listbox.

-MB -- Messagebox

Syntax

wizapp MB
wizapp MB INFORMATION
wizapp MB EXCLAMATION
wizapp MB STOP
wizapp MB QUESTION

Variables used

watitle Sets the title of the message box
watext Sets the text of the message box

Options

INFORMATION Use the information icon for the message box (a white icon with a blue 'i' in it), and an OK button.
EXCLAMATION Use the exclamation icon for the message box (a yellow triangle with an exclamation mark in it), and an OK button.
STOP Use the stop icon for the message box (a red circle with a cross in it), and an OK button.
QUESTION Use the question icon for the message box (a white icon with a question mark in it), and an OK and a Cancel button.
When no option is provided, INFORMATION is used.

Description

This command shows a simple message box on the screen, with one of the standard Windows message box icons. The first three options (INFORMATION, EXCLAMATION and STOP) result in a message box with only one button, labeled 'OK'.

Screenshot of an information messagebox  Screenshot of an exclamation messagebox  Screenshot of a stop messagebox 

The QUESTION option gives a dialog box with two buttons, an OK button and a Cancel button.

Screenshot of a question messagebox

You can examine the errorlevel returned to determine which button was pressed.

The labels of the buttons cannot be changed. They will be 'OK' and 'Cancel' in whatever language the version of Windows is that runs on your machine.

-PB -- Progress bar

Syntax

wizapp PB OPEN
wizapp PB UPDATE <percentage>
wizapp PB CLOSE

Variables used

watitle Sets the title of the dialog box.
wasig Sets the bottom-left signature text of the dialog
watext Sets the text of the dialog box.
wabmp Sets the sidebar picture of the dialog box.
waico Sets the icon for wizard-style dialogs
wasound Sets the sound to play upon starting a wizard-style dialog

Description

With this command you can show a progress bar. The progress bar can be updated to a percentage while time-consuming operations are performed in the background. After the operations have completed, the window can be closed.

Screenshot of a dialog with a progress bar

To use a progress bar, it must be opened first. Unlike other commands, this command returns control to the batch file immediately, so that the work can go on while the progress bar is on the screen. Control is returned to the calling batch file even if start /w is used.

    start /w wizapp PB OPEN

It is not necessary to check the errorlevel returned, as it will always be 0.

Upon startup, an empty progress bar is shown, i.e. 0% progress. Now you can start the first step of the time-consuming work, and after that update the progress bar:

    start /w wizapp PB UPDATE 15

This will send a message to the progress bar window, telling it that it should fill the progress bar to 15%.

If any of the variables watitle, wasig, watext, wabmp or waico changed, these changes will be reflected in the dialog box. If wasound is set, it will be played again. If you want the sound to play only when the dialog is open, you should empty wasound before calls to UPDATE.

If the user pressed the Cancel button on the progress bar dialog, the usual errorlevel 2 will be returned by this call to UPDATE. However, the progress bar will not be closed automatically.

The Back and Next buttons are disabled in a progress bar window.

After the progress bar is completely filled, or when the user pressed Cancel, you can make the progress bar go away with the CLOSE command:

    start /w wizapp PB CLOSE

This will send a message to the progress bar window telling it that it should close. Again, the errorlevel returned here can be 2 when the user pressed Cancel just before closing.

It is the responsibility of the calling program to handle the Cancel button in a correct way, e.g. ask the user for a confirmation and then undo the operations done so far.

Some care should be taken when working with progress bars:

  • The percentage given in the UPDATE command is an absolute number. It is the responsibility of the calling program to make it go up all the time, and to make it go up by steps proportional to the time spent.
  • The progress bar can only be updated between operations. If the time-consuming operation consist of copying one enormous file, this progress bar is of little use.
  • When an UPDATE or CLOSE command is issued, this goes to one of any progress bar windows that are currently open. The one that was active most recently is updated or closed. If you have more than one program running that uses the Wizard's Apprentice to display a progress bar, their progress bars might behave erratically. This will normally not interfere with the correct operation of those programs, though.

-RB -- Radiobuttons

Syntax

wizapp RB

Variables used

watitle Sets the title of the dialog box.
wasig Sets the bottom-left signature text of the dialog
watext Sets the text of the dialog box.
wabmp Sets the sidebar picture of the dialog box.
waico Sets the icon for wizard-style dialogs
wasound Sets the sound to play upon starting a wizard-style dialog
wainput Sets the labels for the radiobuttons. Only the first 10 items are used.
wafile Alternatively sets the labels for the radiobuttons. Only the first 10 items are used.
wabat Sets the batch/script file that is used to return selection information.
wascript Alias for wabat. If both are set, wabat wins.
waassign Template for the assignment expression. This is used to write wabat or wascript.
waoutput In: Sets the radiobutton selected by default;
Out: Returns the radiobutton selected by the user.
waoutnum In: Sets the radiobutton selected by default;
Out: Returns the radiobutton selected by the user.

Description

This command shows a set of maximum ten radiobuttons in a wizard-style dialog on the screen. A set of radiobuttons always has one item selected.

Screenshot of a dialog with a set of radiobuttons

The labels of the radiobuttons can be set in two ways: by setting wainput or wafile. wainput contains a list of labels, separated by the list separator character. wafile is the name of a file in which each line is added as a label to the buttons. If you set both, wafile gets preference and the contents of wainput are not used.

You can initialise the radiobuttons in two ways: either set waoutnum to a zero-based index in wainput, or set waoutput to an item from wainput. Only one item should be selected; if you accidently specify more, only the last item will be selected.

To retrieve the selection the user made you have to set the name of the batch/script file before displaying the dialog, and call that batch/script file afterwards. You can then examine the value of waoutput and waoutnum.

waoutput contains the item selected from wainput; waoutnum contains a zero-based index in the list.

You can never have more than 10 radio buttons. If you have more items to choose from, you can use a single selection listbox instead.

-SPLASH -- Splash screen

Syntax

wizapp SPLASH OPEN
wizapp SPLASH UPDATE
wizapp SPLASH CLOSE

Variables used

wabmp Sets the picture of the splash screen.
waico Sets the icon for the splash screen.
wasound Sets the sound to play upon showing the splash screen.

Description

The SPLASH commands show a splash screen, e.g. during startup of your program. You can update the bitmap, icon and sound of a visible splash window. When startup things are done, the window can be closed.

Screenshot of a splash screen

To show a splash screen, you open it first; unlike other commands, this command returns control to the calling program immediately, so that the work can go on while the splash screen is shown. Control is returned to the calling program even if start /w or some other means of synchronous program execution is used.

    wizapp SPLASH OPEN

It is not necessary to check the errorlevel returned, as it will always be 0.

You can change the bitmap and icon of a visible splash window, or play another sound. For this, you change the value of wabmp, waico and/or wasound and make the following call.

    start /w wizapp SPLASH UPDATE

The properties of the existing splash screen will change, without closing it, and the sound will be played.

You can make the splash screen go away with the CLOSE command:

    start /w wizapp SPLASH CLOSE

This will send a message to the splash screen telling it that it should close.

Some care should be taken when working with a splash screen:

  • When a CLOSE or UPDATE command is issued, this goes to one of any splash screens that are currently open. The one that was active most recently is addressed. If you have more than one program running that uses the Wizard's Apprentice to display a splash screen, their splash screens might behave erratically. This will normally not interfere with the correct operation of those programs, though.

-TB -- Textbox

Syntax

wizapp TB

Variables used

watitle Sets the title of the dialog box.
wasig Sets the bottom-left signature text of the dialog
watext Sets the text of the dialog box.
wabmp Sets the sidebar picture of the dialog box.
waico Sets the icon for wizard-style dialogs
wasound Sets the sound to play upon starting a wizard-style dialog

Description

This command shows a wizard-style dialog on the screen containing only static text. The text can be as large as the dialog.

Screenshot of a dialog with only text

This command can be used for a welcome text in a wizard.

*Batch programming

Although the batch language is not as powerful as other programming languages, it has some clear advantages: It is available on every Windows machine without installing anything, and makes it very easy to "glue together" external programs. That is why the Wizard's Apprentice can be a very powerful combination with some smart batch programming. Setting up a good Wizard in the batch language isn't entirely straightforward, though; that is why this part of the manual is entirely devoted to getting that right.

The first few sections in this part show how to get the control flow right in a batch file; the later sections explain how some common tasks can be done in batch files.

-Moving back and forth

Here's an outline for a wizard with three pages:

  1.   :page1
  2.   start /w wizapp NOBACK TB
  3.   if errorlevel 2 goto :cancel
  4.   rem errorlevel 1 is impossible, no back button!
  5.   :page2
  6.   start /w wizapp LB SINGLE
  7.   if errorlevel 2 goto :cancel
  8.   if errorlevel 1 goto :page1
  9.   :page3
  10.   start /w wizapp FINISH TB
  11.   if errorlevel 2 goto :cancel
  12.   if errorlevel 1 goto :page2
  13.   rem The wizard has ended: do the work!
  14.   ...
  15.   :cancel

Line 1, 5 and 9 are labels, set in the beginning of a page's handling. If in any page the Back button is hit, the batch file jumps back to the label of the previous page, redisplaying that page. Those jumps are in line 8 and 12. If the Next button is hit, the errorlevel is 0; in that case, no jump is done, so the batch file execution just continues with the next line. If the errorlevel is 2, the cancel button is pressed; here we just jump to the :cancel label, which terminates the batch file without doing anything.

A really nice wizard always remembers the choices that you made earlier, so that if you go back and forth, you don't have to make your choices again. This is done by setting the variables waoutput or waoutnum before displaying a wizard page; the values set serve as a default. Here's an example of how to handle that:

  1.   rem Beginning of batch file: set defaults
  2.   set name=Nobody
  3.   ...
  4.   :page12
  5.   set page=:page12
  6.   set wabat=%TEMP%\wabat.bat
  7.   set watext=Enter your name:
  8.   set waoutput=%name%
  9.   start /w wizapp EB PLAIN
  10.   if errorlevel 2 goto :cancel
  11.   if errorlevel 1 goto :page11
  12.   call %wabat%
  13.   set name=%waoutput%
  14.   ...

Before the wizard is started, the batch file sets defaults for all the information needed. As an example, her name is set to "Nobody" in line 2.

Before asking the user to enter his or her name, waoutput is set to the value of name that we now have; initially that is "Nobody". Setting waoutput has the effect that that value is filled in in the editbox when it is displayed.

After the page was displayed, name is set to the value the user entered (in line 13.) This makes sure that if we ever return to this page (e.g. by pressing the Back button in page 13) that value is used as the initial value in the edit box.

-The Cancel confirmation dialog

For a more sophisticated handling of the cancel button, a slightly more complex batch file is needed:

  1.   :page6
  2.   set page=:page6
  3.   start /w wizapp LB SINGLE
  4.   if errorlevel 2 goto :cancel
  5.   if errorlevel 1 goto :page5
  6.   ...
  7.   goto :exit
  8.   :cancel
  9.   set watext=Do you want to abort this wizard?
  10.   start /w wizapp MB QUES
  11.   if errorlevel 2 goto %page%
  12.   :exit

In line 2, we set the environment variable page to :page6. This is the label of the page that is currently handled. Then the page is displayed in line 3. If the user hit the Cancel button, we jump to the :cancel label just as before, but this time a message box is displayed, with a confirmation question (lines 9 and 10.) If the user answers "No" to the question, we jump back to the label %page%, which is of course the label :page6.

We can now include the set page= statement for every page, and go to the same :cancel label every time; we then always return to the page where we left. If the user confirms the question, though, the batch file execution continues at line 12, where the batch file ends.

The goto :exit in line 7 is needed to make sure we don't fall through into the cancel dialog handling after the whole wizard is finished. Together with setting page to the return point, this is a common technique to simulate subroutines in batch files.

-Skipping pages

Sometimes, the answer to one question takes away the need of displaying another page of a wizard. We then need a way to skip a certain page in the wizard. The main complication here is that a wizard can be traversed in two directions, since the user can press the Next or the Back button. Here's an outline that shows how to handle that situation.

  1.   :page4
  2.   set page=:page4
  3.   set wabat=%TEMP%\wabat.bat
  4.   set watext=Should a backup be made?
  5.   set wainput=Make a backup;Don't make a backup
  6.   set waoutnum=%dobackup%
  7.   start /w wizapp RB
  8.   if errorlevel 2 goto :cancel
  9.   if errorlevel 1 goto :page3
  10.   call %wabat%
  11.   if "%waoutnum"=="1" set dobackup=1
  12.   if "%waoutnum"=="0" set dobackup=0
  13.   :page5
  14.   if "%dobackup%"=="0" if %page%==:page4 goto page6
  15.   if "%dobackup%"=="0" if %page%==:page6 goto page4
  16.   set page=:page5
  17.   set watext=Choose a directory for the backup.
  18.   start /w wizapp FB DIR
  19.   if errorlevel 2 goto :cancel
  20.   if errorlevel 1 goto :page5
  21.   ...
  22.   :page6
  23.   set page=:page6

In line 3 to 6, the environment variables are set to show radio buttons on the screen, offering the choices "Make a backup" and "Don't make a backup" to the user. Line 11 and 12 examine the answer given, and set the variable dobackup accordingly.

If the user chose not to make a backup, page 5 can be skipped. This is what is done in line 14. However, line 14 also check from which page the user came; if page is :page4, the user pressed the Next button on that page, so we should skip to page 6. Line 15 handles the case where the user pressed the Back button in page 6 in a similar way; it then jumps back to page 4.

-Advanced batch techniques

Now that we have a nice way to add a user interface to batch files, a lot of possibilities open up. Although it strictly is not within the scope of this manual to teach batch programming, this section outlines a few useful but sometimes strange techniques to get things done in batch files. For more elaborate work on batch programming, consult the following websites:

-Checking whether a filename or directory name is valid

This seemingly simple problem has a lot of strange subtleties. First of all, there are two different cases: checking whether a file exists, or checking whether it could be created. Then there is a difference between Windows 95/98/Me and Windows NT/2000/Xp. A solution that works for all cases does not exist, but these techniques come close.

Here's a simple check whether a file exists:

    rem Check if file exists
    if exist "%file%" echo File exists!

That is the most easy case. However, on Windows NT/2000/Xp this will also work when %file% is a directory. The old trick of checking for %file%\nul is not working with long file names, so there is no other choice than to use dir and find:

    dir "%file%" | find "Directory of" | find /i "%file%"
    if errorlevel 1 echo Directory does not exist!

What is done here is that a directory listing of the specified file is made; Then we search the line containing Directory of <dir>, and check whether the name appears on that line. A catch here is that if %file% contains double quotes, the find command does not work.

A simple batch file to remove double quotes that are not necessary:

    @echo off
    rem UnQuote.bat: removes quotes from %1,
    rem setting the variable in %2
    mkdir TMP###TMP
    cd TMP###TMP
    echo Test > %1
    for %%f in (*.*) do set %2=%%f
    cd ..
    rmdir /s /q TMP###TMP

Here's how to use it:

    @echo off
    set file="A long file name"
    echo %file%
    call unquote %file% file
    echo %file%

The output of this batch file is

    "A long file name"
    A long file name

Another way to check whether a directory exists is to write a file to it:

    echo This is a test > "%file%\tmp.tmp"
    if exist "%file%\tmp.tmp" echo Directory is writable!
    if exist "%file%\tmp.tmp" del "%file%\tmp.tmp"

Caution: If the file tmp.tmp already existed in the directory, it is lost, so you should first check for that.

A similar trick can be used to see whether a file is writable:
    echo This is a test > "%file%"
    if exist "%file%" echo File is writable!
    if exist "%file%" del "%file%"

Before doing this, you should check whether a file of that name already exists, or else it will be deleted.

A similar problem is to check whether a filename contains wildcards, e.g. '?' or '*'. Here is how to do that:

    for %%f in ("%file%") do if %%f=="%file" goto :nowild
    echo "%file%" contains wildcards!
    goto :end
    :nowild
    echo "%file%" contains no wildcards!
    :end 

This for command matches %%f with every file that is in the set %file%. If that is only one file, %%f equals "%file%" in the test. Note that this again only works if %file% does not contain quotes.

-Differences between Windows 95/98/Me and NT/2000/XP

Windows 95/98/Me uses a command processor that is called command.com. In Windows NT/2000/Xp a newer command processor is used, cmd.exe, that has a lot more capabilities. Although the Wizard's Apprentice can be used in both command processors, and all the examples in this manual should work in both, there are some differences that should be noted.

command.com can never have a command line longer than 128 characters. In cmd.exe the longest line is 8192 characters.

cmd.exe has a more commands. Here are a few that are worth looking at. This is only a short summary; refer to the Windows Help file for a detailed explanation.

CommandMeaning
pushdSwitch to another directory, but remember the directory we come from.
popdSwitch back to the directory we came from with the last pushd.
for /dSame as for %%f in (), but loops only over directories.
for /rSame as for %%f in (), but loops over a whole directory tree.
for /f Loop over the lines in a file, or over the lines of the output of a command.

-.inf file for creating shortcuts

Creating a shortcut in a batch file involves some very black magic, even though it seems simple. For a good explanation of how to do it, read the following web site:

Basically, it involves creating a .inf file and then calling RunDLL to do the job. I'll give an example here.

Assume you want a shortcut to the file "c:\winnt\notepad.exe" in the directory "c:\temp", and you want it named "Another Notepad Shortcut". You'd write the following .inf file:

  1.   [version]
  2.   signature=$chicago$
  3.   [DefaultInstall]
  4.   UpdateInis=AddLink
  5.   [AddLink]
  6.   setup.ini, progman.groups,, ""group1="c:\temp\"""
  7.   setup.ini, group1,,"""Another Notepad Shortcut"",""""""c:\winnt\notepad.exe"""""""

Don't get distracted by all the double quotes; there is some system in this mess. First of all, both lines in the [AddLink] section consist of four, comma-separated parts: setup.ini, a group name, an empty part and one last part, that is enclosed in quotes. Secondly, witin this last part, every sub-part is quoted; and thirdly, filenames are quoted. The name of the file the shortcut links to, in this case "c:\winnt\notepad.exe", is quoted six times in total. This makes sure no problems occur when it is a long filename.

To actually create this shortcut, you run the following command:

            
    start /w rundll32.exe setupapi,InstallHinfSection
        DefaultInstall 132 <inffile>

All on one line, with no spaces but one comma between setupapi and InstallHinfSection, and with the full path name of your .inf file as the last argument. This will magically create a shortcut file (a .lnk file), which you can then move around if you want to.

-Increasing the environment size

The Wizard's Apprentice uses the environment to store its state. The environment is a fixed size storage area in the command processor. All environment variables and their values must fit in it.

On Windows 95/98/Me, the default environment size is rather small. This might mean that a batch file runs out of environment space. An error message will appear, "Out of environment space", and variables will no longer be stored.

To increase the size of the environment for a certain batch file, you could create a PIF file for it and always run the batch file through this PIF file. Alternatively, on Windows 95/98/Me, you could specify the environment size of your command processor in the file config.sys in your root directory. You can add the following line to it (or modify it if a SHELL= line already exists):

    SHELL=c:\command.com /e:2048

However, this only changes the size of the environment on your own PC, and will not guarantee that your batch files run somewhere else.

There is a solution that will work on all systems, though. It is possible to set the size of the environment for a command processor using the /e switch.

    command.com /e:2048

Better still, since the full path of the default command processor is always in the environment variable COMSPEC, you could use

    %COMSPEC% /e:2048

Now, you can write your batch file as follows:

  1.   @echo off
  2.   if not "%1" == "EnvSizeIncreased" %COMSPEC% /e:8192 /c %0 EnvSizeIncreased %1 %2 %3 %4 %5 %6 %7 %8 %9
  3.   if not "%1" == "EnvSizeIncreased" goto :end
  4.   if "%1" == "EnvSizeIncreased" shift
  5.   ... the rest of your batch file
  6.   ...
  7.   :end

What this does is the following: in line 2, it is checked whether the first argument passed to this batch file is the word "EnvSizeIncreased". (It is assumed that no user will actually pass this parameter.) If this is not the case, the following happens:

  1. A new command processor is started, of which the environment size is set to 8192 bytes using the /e parameter;
  2. The /c switch is used to tell that command processor to execute a command;
  3. The command it should execute is "%0", which denotes our batch file itself
  4. The command line parameters that are passed to this second instance of our batch file are "EnvSizeIncreased" plus all original parameters.
After this new instance of the batch file has ended, the original instance of the batch file will quit. So all the work is done in the second instance of the batch file.

Now let's see what that second instance of the batch file will do. Because the first parameter passed in is "EnvSizeIncreased", it will skip line 2 and 3. Line 4 tells it to shift all its command line parameters one position, i.e. %2 becomes %1, %3 becomes %2 etc. This will renumber the parameters to their original positions. Then it goes on doing the real work, and after it is done, the second command processor will close automatically, falling back into the first one.

-An annotated example

wainstall.bat is an example batch file that illustrates most of the techniques explained before. It comes with your Wizard's Apprentice distribution; you can actually run it to see how it works.

This batch file is a simple installer for the Wizard's Apprentice itself. It will first show a welcome screen and a license text. It will then ask to user for a directory to install the program in, and ask whether the user wants to create some shortcuts. Finally, it will install the program according to the options set.


Dion Nicolaas
dionnicolaas@users.sourceforge.net

The Wizard's Apprentice's Home
http://wizapp.sf.net