:: Creating a Boot Menu ::

To create our boot menu we will be using CD Shell 2.0.11. If you choose to use the old diskemu.cmd method, you are more than welcome to. However, that method will not be discussed here. There are many benefits to using CD Shell. Directory listing in CD Shell is more organized and clean looking. You can use colors. You can view .txt files without having to open them in the ugly blue DOS "Edit" screen. You can even debug your menus without having to burn a cd or load an ISO into Virtual PC or VMware.

You can find my actual CD Shell file in the "Downloads" section. Take a look at my cdshell.ini file while you read through this to get an understanding of how CD Shell scripting works. If you copy this file into your BOOT folder and run the debugger, you can see exactly how my boot menu looks and operates. Don't worry about accidently running some program, the debugger will not actually execute any files if you choose any of the options, but it gives you an idea of what happens.

Here is an example of a possible boot menu created with CD Shell:

If you followed the "Getting Started" guide you should have a folder called BOOT in your AIO-DVD directory. The cdshell.ini file is what will contain the code for our menu. Open that file in Notepad or your favorite text editor.


About CD Shell Scripting

CD Shell uses an extensive scripting language to create the boot menu, much like writing php or java scripts. There is much more it can do than I will be covering in this guide, but I will provide you with the information to get your boot menu up and working.

For more information and help with CD Shell please consult the following site: http://www.cs.uic.edu/~mter/cdshell/buildcd.html

More documentation is available on that site under Information -> Documentation.


Creating Sections

Sections are used to keep the code clean and organized, and allow commands to jump to certain sections to execute specific code. To create a section type the name of the section followed by a colon. I like to call my very first section menu:. Keep in mind that code is executed exactly in the order it is listed. So always make sure that after operating system sections to create a key section for that OS. You will see what I mean when we get to Operating System Sections.

Examples of sections:

boot:
xp_pro:
moreoptions


Printing the Interface

cls
print "1) Windows XP Professional SP1 Corporate \n"

The cls command will first clear the entire screen before printing text. ALL printed text must be enclosed in quotes. Multiple print commands can be used on a line by using a semicolon (;) after each command. The \n command creates a line return. If we wanted a space between our menu options we would just use \n\n after the first print command or before the next print command.

To center, left align, or right align text, use the c, l, and r commands.

print c "This is an example of centered text"

If you just want a comment, use the # character.

# This is a comment. It will not print anything on the screen.


User Input

Let's create a section called MainKey:. This section should be placed after the menu: section. Here are the first two lines of my MainKey section:

MainKey:
getkey 20 boot 0x80
if $lastKey == key[1]; then goto XP_Pro

The first line creates the section name. The second line uses the getkey command to catch the key the user presses. The 20 is a timeout. It means that if no key is pressed within 20 seconds, the command boot 0x80 will run. boot 0x80 boots the first hard drive on the system. If no OS is installed then nothing will boot of course. You do not have to include a timeout. If you don't, the menu will stay on the screen until you do something.

The last line uses an if command to check the key press. It says that if the last key pressed was "1", then it will goto the XP_Pro section.


Running Files and Jumping to Sections

chain /PRO1.DAT
Runs the PRO1.DAT file. The forward slash "/" tell CD Shell that PRO1.DAT is in the root of the cd.

memdisk /98SE.IMA
Runs the image of our 98 SE boot disk to start the setup for Windows 98 SE. The memdisk command must be used for image files (.IMG or .IMA).

goto XP_Pro:
Jumps to the "XP_Pro:" section and executes the code there.

type /example.txt
Prints the contents of example.txt onto the screen. It does not actually open the file, it just inputs the contents onto the screen.


Operating System Sections

Using the "User Input" directions as an example, let's now create a section called XP_Pro:. Each OS section must also be followed by it's own key section. This section will create a new menu with our XP options. Here is my "XP_Pro" section code. Note that the "Ä" character when used repeatedly will print a continuous line, instead of using hyphens which produces something like "-----".

XP_Pro:
cls
print r "\n\cXXPress \c0BF1 \cXXfor Help \n"
print c "\n\cXXMicrosoft Windows XP Professional SP1 Corporate \n"
print c "\cXXÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ \n"
print "1) Regular \n"
print "2) Unattended \n"
print "3) OEMPreinstall \n"
print c "\n\n"
print "Press any key to return to main menu... \n"

XP_Pro_Key:
getkey 20 goto menu
if $lastKey == key[1]; then chain /PRO1.DAT
if $lastKey == key[2]; then chain /PRO2.DAT
if $lastKey == key[3]; then chain /PRO3.DAT
if $lastKey == key[F1]; then goto Help
goto menu

Here is what happens. The computer prints what is in the XP_Pro: section and then continues on to the next section XP_Pro_Key:, which uses the getkey command. So the computer waits for a key press. If the key pressed is "1", then the computer will then proceed to run the PRO1.DAT file which should begin the XP setup process. If no key is pressed in 20 seconds CD Shell will jump back to the main menu.

IF you only want one option for XP and do not need the extra menu, then skip the "XP_Pro:" and "XP_Pro_Key:" sections and in the User Input part of this guide:

if $lastKey == key[1]; then goto XP_Pro

can be changed to

if $lastKey == key[1]; then chain /PRO1.DAT


More Options

I use a MoreOptions: section in my menu for things like Partition Magic 8.0, Norton Ghost, viewing serial numbers, etc. You will need to create the proper entries in your "menu:" and "MainKey:" sections of your "cdshell.ini" file.

MoreOptions:
cls
print r "\n\cXXPress \c0BF1 \cXXfor Help \n"
print c "\n\cXXMore Options \n"
print c "\cXXÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ \n"
print "1) Read/Copy Files From NTFS Volumes To FAT32/16 Drives \n"
print "2) Partition Magic 8.0 \n"
print "3) Norton Ghost \n"
print "4) View Serial Numbers \n"
print c "\n\n"
print "Press any key to return to main menu... \n"

MoreOptions_Key:
getkey 20 goto menu
if $lastKey == key[1]; then memdisk NTFS.IMA
if $lastKey == key[2]; then memdisk PM8.IMG
if $lastKey == key[3]; then memdisk GHOST.IMA
if $lastKey == key[4]; then goto SerialNumbers
goto menu


Setting Colors - OPTIONAL

I would worry about setting colors AFTER you have everything else working and down pat.

Use the following commands at the very beginning of your first section to set colors for the whole boot menu.

menu:
set textColor= color[grey on black]
set boldColor= color[cyan on black]

Valid color names are: black, blue, green, cyan, red, magenta, brown, grey, brightgrey, brightblue, brightgreen, brightcyan, brightred, brightmagenta, yellow, and white.

To highlight specific portions of text with a different color use the \cXX and \cxx commands. \cXX indicates that the text following it is the bold color, and \cxx says the text following it reverts back to normal color. If you want to use more colors without having to set the color each time, then XX will be replaced with two numbers, the first indicating the background color and the second indicating the text color. So:

print "\cXXThis text is boldcolor. \cxxThis text is normal color."

Prints "This text is boldcolor" in cyan on black and then prints "This text is normal color." in grey on a black background

Code Color Code Color
0 black 8 grey
1 blue 9 brightblue
2 green A brightgreen
3 cyan B brightcyan
4 red C brightred
5 magenta D brightmagenta
6 brown E yellow
7 brightgrey F white

So if you look at the screen shot at the beginning of the guide and the following code you can see what happens:

print l "\cXXPress \c0BF1 \cXXfor Help"; print r "\c0Bckite@portraitofakite.com \n"

The word "Press" is printed in cyan on a black background, then "F1" is printed in bright cyan on a black background. "For Help" is printed in the cyan again, and then my e-mail is printed again in the brightcyan color.


The End

The very last line of your cdshell.ini file MUST read end.

end

That's all. The end command signifies the end of the script and will bring you to a cd shell command prompt. It is much like a dos command prompt but supports more commands and has a nicer directory listing display. Type HELP at the prompt to see all what you can do.


Debugging

One of the greatest things about cdshell is debugging. To debug just double click the file cdshw.com in the BOOT folder. This will run a simulation of what the boot process will look like. Don't worry about accidentally installing XP or anything like that, because the debugger does not allow actual commands to be executed. To exit the debugger type exit at the command prompt. If you can't access the command prompt then just Ctrl+Alt+Del out.


Extra Fun

The following code I place as the VERY beginning code in my cdshell.ini file. It does a few things:

First, it starts off with a boot: section. This section first prints "Press enter to boot from DVD..." before the menu. If Enter is not pressed in 5 seconds, it boots whatever OS is loaded onto the first hard drive and skips the menu.

The next two sections are custom functions I wrote to print out the current date and time. An example of this can be seen in the screen shot at the top of this page.

boot:
cls
print "\n"
print "Press Enter to boot from DVD... \n"
getkey 5 boot 0x80
if $lastKey == key[enter]; then goto time
# When no key found...
goto boot

# Function to display time of day
time:
set hour = $timeHour
set ampm = "am"
if $timeHour > 12; then set hour = $timeHour - 12
if $timeHour > 12; then set ampm = "pm"
set time = "$hour:$timeMinute$ampm"

# Function to display date
date:
set month = "n/a"
if $dateMonth == 1; then set month = "Jan."
if $dateMonth == 2; then set month = "Feb."
if $dateMonth == 3; then set month = "Mar."
if $dateMonth == 4; then set month = "Apr."
if $dateMonth == 5; then set month = "May."
if $dateMonth == 6; then set month = "Jun."
if $dateMonth == 7; then set month = "Jul."
if $dateMonth == 8; then set month = "Aug."
if $dateMonth == 9; then set month = "Sep."
if $dateMonth == 10; then set month = "Oct."
if $dateMonth == 11; then set month = "Nov."
if $dateMonth == 12; then set month = "Dec."
set date = "$month$dateDay,$dateYear"

To print the line with the time and date in it I use this piece of code:

print c "\n\cXXÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ<\c0B$time $date\cXX>ÄÄ \n\n"