| Click here to support our advertisers

SOFTWARE FOR SALE
BOOKS FOR SALE
SEARCH CENTRAL
JOB BANK
CLASSIFIEDS
DIRECTORIES
REFERENCE Online Library
LEARNING CENTER
JOURNAL
NEWS CENTRAL
DOWNLOADS
COMMUNITY
CALENDAR
ABOUT US
Journal:
Get the weekly email highlights from the most popular journal for developers! Current issue
> developer.com developerdirect.com htmlgoodies.com javagoodies.com jars.com intranetjournal.com javascripts.com | All Categories : C/C++ vcg24.htm Using Microsoft Setup, the Microsoft Installation Program Configuring Microsoft Setup Using the Sax Setup Wizard Using the InstallSHIELD SDK Version Using InstallSHIELD Professional Modifying the CONFIG.SYS and AUTOEXEC.BAT Files The CD-ROM AutoPlay Facility Using the AUTORUN.INF Files Suggestions for Creating AutoPlay CDs Demos and Shows Using DemoSHIELD Working Demos Summary # - 24 - Creating Distribution Disks for Visual C++ Applications Some Visual C++ database applications might call for a one-time-only installation by you, the developer. If that's the case, you can copy the applications' .EXE, .HLP, and .VBX files, together with any database and ancillary files that might be required, onto a set of disks that you will copy to the appropriate directories of the client's computer. If your Visual C++ database front end will be used by a large number of people, or if you want to impress your clients with a sophisticated setup application similar to those used to install mainstream Windows applications, you need to create "official" distribution disks. This chapter is intended primarily for developers who are creating applications that will be used with Windows 95 and later versions of Windows. The techniques shown here are very useful for versions of Windows earlier than Windows 95; however, it's unlikely that readers of this book will be creating many applications for earlier versions of Windows. In the future, expect Windows NT to offer facilities that are comparable to those offered by Windows 95. Most of the setup tools are part of the WIN32SDK. The AutoPlay facility is entirely part of Windows, and the developer's portion of AutoPlay consists of a five-page Word for Windows document. The InstallSHIELD Professional toolkit expands on the InstallSHIELD SDK product included with Visual C++ 4 and that is part of the WIN32SDK. It's available from InstallShield Corporation. (InstallShield Corporation used to be called Stirling Technologies, Inc. They changed their name to reflect their most successful product.) The WIN32SDK, which is part of the MSDN Level II product, includes Microsoft Setup, the "standard" setup program that has been used extensively by Microsoft and other application vendors. One problem with Microsoft Setup is that it requires the setup program to be created as an application (you edit C source code and then build your own SETUP.EXE program). With InstallSHIELD SDK, you need to modify only a single script file—a much simpler process. The Sax Setup Wizard product from Sax Software is entirely Windows-based. It uses no scripting at all, because all user input is accomplished through wizard dialog boxes. All three installation generator programs described in this chapter create professional installations that will help assure the user that your product is professional and of high quality—an important factor in today's competitive software market. ### Using Microsoft Setup, the Microsoft Installation Program The Microsoft Setup program (which is also referred to as MS Setup or MSSETUP) is based on the design of the wizards included with Access 1.0, which predated the release of Visual C++. The Microsoft Setup program resembles the SetupWizard of the Access 1.1 Distribution Kit (ADK), but the C version uses a different approach to create the distribution files and execute the setup application. The primary differences between the methods used by Visual C++ and the ADK wizards to create the distribution disks are explained in the following sections. NOTE Microsoft no longer supports the Microsoft Setup program. It's still included with Visual C++, but it hasn't changed for some time, and Microsoft won't update it in the future. Unless you're already using Microsoft Setup, you shouldn't consider it for new projects. #### Configuring Microsoft Setup When you use Microsoft Setup, you don't get the same effects as with the other, newer setup programs such as Sax Setup Wizard and InstallSHIELD. For example, the Microsoft Setup program doesn't support the uninstall process automatically. If you use Microsoft Setup, you must write your uninstall code completely on your own, something that both InstallSHIELD and Sax Setup Wizard do for you. Using Microsoft Setup is a multistep process. Follow these steps to create your own setup application: Create your SETUP.EXE program using the sample code provided in the WIN32SDK CD's \WIN32SDK\MSTOOLS\MSSETUP\SAMPLE folder as a starting point. You can customize this sample program from Microsoft for your own purposes. In your version of Setup, you can specify the background bitmap, title, and billboards (messages that tell the user to register the product, and so on). Lay out the files on the distribution media (usually disks, but now more commonly CD-ROMs). To lay out your application, use the DSKLAYT program, shown in Figure 24.1. Figure 24.1. The DSKLAYT program in action. Create the SETUP.INF file and distribution disks. Your setup program uses the SETUP.INF file to control the application installation. The SETUP.INF file contains at least three sections, as shown in Listing 24.1. The DSKLAYT2.EXE program takes the layout file created by DSKLAYT.EXE, as well as the files included with your application, and creates the SETUP.INF file for you. The DSKLAYT2.EXE program also creates distribution media images, each in their own directory. Listing 24.1. A sample SETUP.INF file.
>     [Source Media Descriptions]

>         "1", "Disk 1", "", ""

>     [Minimum Files]

>           1, setupapi.c,,,COPY,1992-01-30,,,,,,,,,,52174,,999,,,

>     [Extra Files]

>           1, sample.inf,,,!COPY,1992-01-30,,,,,,,,,,10,,999,,,

>     [Default File Settings]

>     "STF_BACKUP"     = ""

>     "STF_COPY"       = "YES"

>     "STF_DECOMPRESS" = "YES"

>     "STF_OVERWRITE"  = "ALWAYS"

>     "STF_READONLY"   = "YES"

>     "STF_ROOT"       = ""

>     "STF_SETTIME"    = "YES"

>     "STF_TIME"       = "1"

>     "STF_VITAL"      = "YES"
> Figure 24.2 shows the process of developing your application's distribution disks. Note that the DSKLAYT2.EXE program is a DOS-based application that runs in a DOS window under Windows 95 and Windows NT. This application won't run under Windows 3.x or native-mode DOS because it's an NT console mode application. Figure 24.2. The Microsoft Setup process. ### Using the Sax Setup Wizard Sax Software markets an application installation system called the Sax Setup Wizard. This product was initially developed for Windows 3.x; it now fully supports Windows 95. The Sax Setup Wizard is a powerful yet easy-to-use setup generator, excellent for many types of projects. Using Sax Setup Wizard is much simpler than using the Microsoft Setup program. Sax Setup Wizard is a totally Windows-based installation program that offers extensive user feedback to assist in creating installation disks. Sax Setup Wizard can create not only disk-based installations but also installations for CD-ROM-based products. This is very helpful, because the AutoRun facility (described later) can call the Sax Setup Wizard-created setup program if needed. Sax Setup Wizard is a single program that requires no additional scripts or other manual input from the user. This differs from Microsoft Setup and InstallSHIELD, both of which are multistep processes that require some form of script from the user. Figure 24.3 shows Sax Setup Wizard's main window before a project has been opened. Figure 24.3. Sax Setup Wizard's main window. After a project has been opened, the values defined by the programmer are displayed in Sax Setup Wizard's main window, as shown in Figure 24.4. Figure 24.4. Sax Setup Wizard's main window with a project opened. The main thing the user sees when installing applications is the installation program's background. All installation programs let you set the background when the setup program is being developed, and Sax Setup Wizard is no different. With Sax Setup Wizard, you can configure the shading (the trend for a gradient color in installation programs has almost become the standard). Also, your application's title can be text. You specify this in the General tab of the Project Options dialog box, shown in Figure 24.5. Figure 24.5. Sax Setup Wizard's Project Options dialog with the Background tab open. Building a distribution disk set is a simple process with Sax Setup Wizard. You can specify the destination (most of the time you will build to a directory on a hard disk) and the disk size (you can choose from all of the common sizes, including CD-ROM distribution media, which offers a virtually unlimited size), or e-mail distribution. After you have configured the distribution of your application and generated the disk images, you can copy these images to disks and distribute your application. If I were writing a review, I'd certainly rate the Sax Setup Wizard as the easiest setup generator currently on the market. ### Using the InstallSHIELD SDK Version The documentation from InstallShield Corporation refers to the InstallSHIELD SDK version as InstallSHIELD SE. This chapter uses the same designation. InstallSHIELD SE is a basic application installation system that is very compatible with Windows 95. Applications that are installed using InstallSHIELD SE can be easily removed later using the Add/Remove Programs option under the Windows 95 Control Panel applet. The InstallSHIELD SE program works like this: Either write or modify an existing script file to be used with your application. Process the script file using the InstallSHIELD SE "compiler" to create the installation script that the InstallSHIELD SE Setup program will use for input. Process all temporary resource files (such as bitmaps, DLLs, and dialog boxes) using the ICOMP.EXE program to create the _SETUP.LIB file that the Setup program uses. Use the ICOMP.EXE program to process your application's file(s) and create a single (compressed) output (.Z) file that is used by Setup. For larger applications that will require more than one disk, use the SPLIT.EXE program to split the .Z file that you created in step 4. If your entire application with the InstallSHIELD SE files will fit on a single disk, you don't need to use SPLIT.EXE. Figure 24.6 shows the process of creating a distribution disk set for a Windows 95 application. Figure 24.6. The InstallSHIELD SE process. Take a look at each of the files you must create in order to use InstallSHIELD SE. This example uses the files from InstallShield Corporation's sample program because they represent an excellent starting point and can be easily modified to work with different applications. The first file you need is the rules file. This file, which is a standard text file created using any editor you want (such as Notepad), is shown in Listing 24.2. The rules file is processed using the InstallSHIELD SE Compile program. The Compile program converts the rules file into an .INS file, which must be named SETUP.INS and be placed on the first disk of your product's distribution disk set, where the InstallShield SE program will look for it. NOTE The files shown in the listings for InstallSHIELD SE are all found in the InstallSHIELD SE directory of the WIN32SDK. They are not found on this book's CD-ROM. Listing 24.2. SETUP.RUL: The rules file.
>     /*----------------------------------------------------------------------------\

>         IIIIIIII SSSSSSSS

>            II    SS                     InstallSHIELD SDK Edition (R)

>            II    SSSSSSSS            1995, Stirling Technologies, Inc.

>            II          SS                   All Rights Reserved.

>         IIIIIIII SSSSSSSS

>         This source code is intended as a supplement to Stirling Technologies,

>         Inc., product documentation.  Refer to your Stirling Technologies, Inc.,

>         product documentation for more detailed information.

>     \-----------------------------------------------------------------------------/

>     /*----------------------------------------------------------------------------\

>             Filename:  SETUP.RUL

>          Description:  InstallSHIELD SDK Edition Template One template script.

>               Author:  Stirling Technologies, Inc.   Date: 2-4-95

>             External

>                Files:

>             Comments:  This template script performs a basic installation to a

>                        Windows 95 or Windows NT platform.  The installation

>                        includes components: Application Program Files, Sample and

>                        Template Files, Online Help Files, and Multimedia Tutorial

>                        Files.  With minor modifications, this template can be

>                        adapted to create new, customized installations.

>        Modifications:  (Precede each entry with "+" sign. Include name and date.)

>                        +                             Date:

>     \----------------------------------------------------------------------------*/

>             // Size of components

>     #define SIZE_REQ_SAMPLES        1400000

>     #define SIZE_REQ_TEMPLATES        10000

>     #define SIZE_REQ_PROGRAM         200000

>     #define APP_NAME                "Sample App"

>     #define PROGRAM_GROUP_NAME      "Sample App Group"

>     #define APPBASE_PATH            "Company\\SampleApp\\"

>     #define COMPANY_NAME            "SampleCompany"

>     #define PRODUCT_NAME            "SampleApp"

>     #define PRODUCT_VERSION         "3.0"

>     #define PRODUCT_KEY             "designer.exe"

>     #define UNINSTALL_KEY           "SampleAppV3"

>     #define APPBASE_DIR95           "Program Files"

>     #define BASE_REGISTRYNT \

>         "Software\\Microsoft\\Windows NT\\CurrentVersion\\App Paths\\"

>     #define BASE_REGISTRY95 \

>         "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\"

>     #define SYS_BOOTMACHINE         3

>     #define STR_COMPLETE95 \

>         "by selecting the program icon in the Programs menu.\n\n"

>     #define STR_COMPLETENT \

>         "by selecting the program icon in the program group.\n\n"

>     declare

>             // --- Global variable definition ---

>             STRING  svGrp, szMsg, szFileSet, szTitle, szAppPath, szAppSharedDir;

>             STRING  szProgram, szTemp, svUninstLogFile, szRegKey;

>             STRING  svMainDirectory[ _MAX_STRING ];

>             BOOL    bSpaceOk, bReshowSetupType;

>             NUMBER  nResult, nStatusId, nType;

>             BOOL    bIncludeProgram, bIncludeSamples, bIncludeHelp, bIncludeTut;

>             BOOL    bWinNT;

>             // --- Function definition ---

>             prototype SetupScreen();

>             prototype CheckRequirements();

>             prototype CheckSpaceRequirements( number, number, number, string );

>             prototype CreateRegDBEntries();

>     program

>     StartHere:

>             Disable( BACKGROUND );

>             // Setup installation screen

>             SetupScreen();

>             // Set installation info that is required for other functions.

>       InstallationInfo( COMPANY_NAME, PRODUCT_NAME, PRODUCT_VERSION, PRODUCT_KEY );

>             // Create a Welcome dialog.

>     WelcomeDlg:

>             Disable( BACKBUTTON );

>             Welcome( "Welcome", 0 );

>             Enable( BACKBUTTON );

>             // --- System test for proper configuration ---

>             CheckRequirements();

>             // --- Ask user for the path to place installed application ---

>     GetTargetDirectory:

>             svMainDirectory = TARGETDISK ^ APPBASE_DIR95 ^ APPBASE_PATH;

>             if ( AskDestPath( "Choose Destination Location", szMsg,

>                               svMainDirectory, 0 ) = BACK ) then

>                goto WelcomeDlg;

>             endif;

>             szAppSharedDir = svMainDirectory ^ "System";

>     DetermineUserSelection:

>             nType = SetupType( "Setup Type", "", svMainDirectory, TYPICAL, 0 );

>             if ( nType = BACK ) then goto GetTargetDirectory; endif;

>             bReshowSetupType = FALSE;

>             switch (nType)

>             case TYPICAL:

>                  bIncludeSamples  = TRUE;

>                  bIncludeProgram  = TRUE;

>                  bIncludeHelp = TRUE;

>             case COMPACT:

>                  bIncludeProgram  = TRUE;

>             case CUSTOM:

>                  SetDialogTitle( DLG_ASK_OPTIONS, "Select Components" );

>                  bIncludeSamples  = TRUE;

>                  bIncludeProgram  = TRUE;

>                  bIncludeHelp = TRUE;

>                  szMsg = "Select the components that you wish to install.\n"+

>                      "If the check box is unchecked, that component will not be "+

>                      "installed. Click Next to continue with the installation.";

>                  nResult = AskOptions( NONEXCLUSIVE, szMsg,

>                                    "Application Program Files", bIncludeProgram,

>                                    "Sample and Template Files", bIncludeSamples,

>                                        "On-Line Help Files", bIncludeHelp,

>                                        "Multimedia Tutorial", bIncludeTut );

>                  if ( nResult = BACK ) then goto DetermineUserSelection; endif;

>                  // Handle exiting of setup

>                  if (nResult = CANCEL) then

>                     if (AskYesNo( "Are you sure you would like to exit setup?", NO)

>                        = YES) then

>                        abort;

>                     else

>                        bReshowSetupType = TRUE;

>                     endif;

>                  endif;

>             endswitch;

>             if (bReshowSetupType = TRUE) goto DetermineUserSelection;

>             // Check space requirements

>             bSpaceOk = CheckSpaceRequirements( bIncludeSamples,

>                                                bIncludeProgram,

>                                                bIncludeHelp,

>                                                svMainDirectory );

>             if (bSpaceOk = FALSE) goto DetermineUserSelection;

>                                          // Ask user to try again

>     FolderSelection:

>             if ( bWinNT ) then

>                svGrp = PROGRAM_GROUP_NAME;

>                // Allow user to modify folder name

>                if ( SelectFolder( "Folder Selection", svGrp, svGrp ) = BACK ) then

>                   goto DetermineUserSelection;

>                endif;

>             endif;

>     FileTransferSetup:

>             // Set the deinstallation information

>             DeinstallStart( svMainDirectory, svUninstLogFile, UNINSTALL_KEY, 0 );

>             RegDBSetItem( REGDB_UNINSTALL_NAME, APP_NAME );

>             // Set APPPATH for the main application

>             szAppPath = svMainDirectory ^ "PROGRAM" + ";" + szAppSharedDir;

>             RegDBSetItem( REGDB_APPPATH, szAppPath );

>             szProgram = svMainDirectory ^ "PROGRAM\\designer.exe";

>             RegDBSetItem( REGDB_APPPATH_DEFAULT, szProgram );

>             // Set APPINFO for auxiliary application

>             if (bWinNT) then

>                szRegKey = BASE_REGISTRYNT ^ "demo.exe";

>             else

>                szRegKey = BASE_REGISTRY95 ^ "demo.exe";

>             endif;

>             RegDBSetDefaultRoot( REGKEY_LOCAL_MACHINE );

>             RegDBSetKeyValueEx( szRegKey, "Path", REGDB_STRING,  szAppPath, -1 );

>             szProgram = svMainDirectory ^ "PROGRAM\\demo.exe";

>             RegDBSetKeyValueEx( szRegKey, "", REGDB_STRING,  szProgram, -1 );

>             // --- Define the file to be copied to the user's machine ---

>             szFileSet = "General";

>             TARGETDIR = svMainDirectory;

>             FileSetBeginDefine( szFileSet );

>               SetStatusWindow( -1, "Copying program files..." );

>               // Always copy readme and related

>               CompressGet( "data.z", "*.*", COMP_NORMAL );

>               if (bIncludeProgram) then

>                  TARGETDIR = svMainDirectory ^ "PROGRAM";

>                  CompressGet( "data.z", "program\\*.*", INCLUDE_SUBDIR );

>                  CompressGet( "data.z", "shared\\*.*", COMP_NORMAL );

>                  TARGETDIR = szAppSharedDir;

>                  CompressGet( "data.z", "shared\\*.*", SHAREDFILE | COMP_NORMAL );

>               endif;

>               if (bIncludeSamples) then

>                  TARGETDIR = svMainDirectory ^ "SAMPLES";

>                  CompressGet( "data.z", "samples\\*.*", INCLUDE_SUBDIR );

>               endif;

>               if (bIncludeHelp) then

>                  TARGETDIR = svMainDirectory ^ "TEMPLATE";

>                  CompressGet( "data.z", "template\\*.*", INCLUDE_SUBDIR );

>               endif;

>             FileSetEndDefine( szFileSet );

>     DoFileTransfer:

>             // --- Set up status bar/file info and perform file transfer ---

>             Enable( EXIT );

>             Enable( STATUS );

>             Enable( FEEDBACK_FULL );

>             StatusUpdate( ON, 90 );

>             // --- Copy all files on all disks ---

>             nResult = FileSetPerformEz( szFileSet, 0 );

>             switch (nResult)

>             case FS_DONE: // --- Successful completion ---

>             case FS_CREATEDIR: // --- Create Directory Error ---

>                MessageBox( "Unable to create a directory under " + TARGETDIR + "."+

>                   "Please check write access to this directory.", SEVERE );

>                  abort;

>             default: // --- Group all other errors under default label ---

>                  NumToStr( szTemp, nResult );

>                  MessageBox( "General file transfer error."+

>                               "Please check your target location and try again."+

>                               "\n\n Error Number:"+szTemp, SEVERE );

>                  abort;

>             endswitch;

>     SetRegistryEntries:

>     //        RegDBSetAppInfo( "Template", REGDB_STRING, "good.tpl", -1 );

>     //        RegDBSetAppInfo( "TemplatePath", REGDB_STRING,

>     //            svMainDirectory ^ "TEMPLATE", -1 );

>             Disable( FEEDBACK_FULL );

>             CreateRegDBEntries( );

>             // --- Create program groups and icons ---

>     CreateFolderIcons:

>             SetStatusWindow( 95, "Creating Folder and Icons...." );

>             if ( bWinNT ) then

>                CreateProgramFolder( svGrp );

>                ShowProgramFolder( svGrp, 0 );

>                LongPathToShortPath( svMainDirectory );

>                Delay(1);

>             endif;

>             TARGETDIR = svMainDirectory;

>             if (bIncludeProgram) then

>                szProgram = TARGETDIR ^ "PROGRAM\\DESIGNER.EXE";

>                if ( bWinNT ) then

>                   AddFolderIcon( svGrp, APP_NAME, szProgram,

>                                  TARGETDIR ^ "PROGRAM",

>                                  "", 0, "", REPLACE );

>                else

>                   LongPathToQuote( szProgram, TRUE );

>                   AddFolderIcon( "", APP_NAME, szProgram,

>                                  TARGETDIR ^ "PROGRAM",

>                                  "", 0, "", REPLACE );

>                endif;

>                Delay( 1 );

>             endif;

>             if ( bWinNT ) then

>                if (bIncludeSamples) then

>                   szProgram = TARGETDIR ^ "PROGRAM\\DEMO.EXE ";

>                   AddFolderIcon( svGrp, "Example1",

>                                  szProgram + TARGETDIR ^ "PROGRAM\\MULTI.DBD",

>                                  TARGETDIR ^ "PROGRAM",

>                                  "", 0, "", REPLACE );

>                   Delay( 1 );

>                endif;

>                if (bIncludeSamples) then

>                   AddFolderIcon( svGrp, "Example2",

>                                  szProgram + TARGETDIR ^ "SAMPLES\\LAUNCHER.DBD",

>                                  TARGETDIR ^ "SAMPLES",

>                                  "", 0, "", REPLACE );

>                   Delay( 1 );

>                endif;

>                AddFolderIcon( svGrp, "ReadmeFile",

>                               "NOTEPAD.EXE " + TARGETDIR ^ "README.TXT",

>                               TARGETDIR,

>                               "", 0, "", REPLACE );

>                Delay( 1 );

>                szProgram = WINDIR ^ "UNINST.EXE";

>                LongPathToShortPath( szProgram );

>                LongPathToShortPath( svUninstLogFile );

>                AddFolderIcon( svGrp, "Uninstaller",

>                               szProgram + " -f" + svUninstLogFile,

>                               WINDIR,

>                               "", 0, "", REPLACE );

>                Delay( 1 );

>             endif;

>             // Setup complete and readme file

>             SetStatusWindow( 100, "Installation complete." );

>         // If shared files could not be installed, users must restart system

>             if (BATCH_INSTALL = TRUE) then

>                szMsg = "Some files could not be installed because they are "+

>              "currently in use by other programs in the system.  "+

>              "To allow for proper operation of the new program you should restart"+

>              "your system at this time.";

>           if (RebootDialog( "Restart Windows", szMsg, SYS_BOOTMACHINE ) = 0) then

>               // Still must ensure proper installation

>               CommitSharedFiles(0);

>           endif;

>         else

>                szMsg = "Setup is complete.  You may run the installed program ";

>                if ( bWinNT ) then

>                   szMsg = szMsg + STR_COMPLETENT;

>                else

>                   szMsg = szMsg + STR_COMPLETE95;

>                endif;

>                MessageBeep( 0 );

>                MessageBox( szMsg, INFORMATION );

>             endif;

>             exit;

>     /*-------------------------------------------------------------------------

>          Name    : SetupScreen

>          Purpose : This function will set up the screen look.  This includes

>                    colors, fonts, text to be displayed, etc.

>     -------------------------------------------------------------------------*/

>     function SetupScreen()

>             begin

>               Enable( DEFWINDOWMODE );

>               Enable( INDVFILESTATUS );

>               SetTitle( APP_NAME + " Setup", 36, WHITE );

>               SetTitle( "Setup", 0, BACKGROUNDCAPTION );  // Caption bar text

>               Enable( BACKGROUND );

>             end;

>     //-------------------------------------------------------------------------

>     //

>     //   Name    : CheckRequirements

>     //

>     //   Purpose : This function will check all minimum requirements for the

>     //             application being installed.  If any fail, the user

>     //             is informed and the installation is terminated.

>     //

>     //-------------------------------------------------------------------------

>     function CheckRequirements()

>               number  nvDx, nvDy;

>               number nvResult;

>               STRING szResult;

>             begin

>               // --- Determine if NT or Windows 95 not --

>               GetSystemInfo( WINMAJOR, nvResult, szResult );

>               bWinNT = TRUE;

>               if (nvResult = 4) then

>                  bWinNT = FALSE;  // Running Windows 95

>               endif;

>               // --- Check screen resolution ---

>               GetExtents( nvDx, nvDy );

>               if (nvDy < 480) then

>           MessageBox( "This program requires VGA or better resolution.", WARNING );

>                  exit;

>               endif;

>             end;

>     //-------------------------------------------------------------------------

>     //

>     //   Name    : CheckSpaceRequirements

>     //

>     //   Purpose : This function will check space requirements based on the

>     //             elements being installed.

>     //

>     //-------------------------------------------------------------------------

>     function CheckSpaceRequirements( bIncludeSamples,

>                                      bIncludeProgram,

>                                      bIncludeHelp,

>                                      szDir )

>               number  nSizeRequired;

>             begin

>               nSizeRequired = 0;

>               // Determine total size

>               if (bIncludeSamples) then

>                 nSizeRequired = nSizeRequired + SIZE_REQ_SAMPLES;

>               endif;

>               if (bIncludeHelp) then

>                 nSizeRequired = nSizeRequired + SIZE_REQ_TEMPLATES;

>               endif;

>               if (bIncludeProgram) then

>                 nSizeRequired = nSizeRequired + SIZE_REQ_PROGRAM;

>               endif;

>               // Space check of target drive

>               bSpaceOk = TRUE;

>               if (GetDiskSpace( szDir ) < nSizeRequired) then

>               szMsg = "There is not enough space available on the disk\n" +

>                      "'" + svMainDirectory + "' \n" +

>                      "Please free up some space or change the target location\n" +

>                      "to a different disk";

>                  MessageBeep(0);

>                  MessageBox( szMsg, WARNING );

>                  bSpaceOk = FALSE;

>               endif;

>               return bSpaceOk;

>             end;

>     //-------------------------------------------------------------------------

>     //

>     //   Name    : CreateRegDBEntries

>     //

>     //   Purpose : This function will create necessary keys and values for

>     //             the sample program.

>     //

>     //-------------------------------------------------------------------------

>     function CreateRegDBEntries()

>             string szKey[255], szValue, szDemo, szProgram;

>     begin

>             // Create PRODUCT_KEY key

>             szKey = "SOFTWARE\\" + COMPANY_NAME + "\\" + PRODUCT_NAME + "\\" +

>                     PRODUCT_VERSION + "\\" + "DESIGNER";

>             RegDBCreateKeyEx( szKey, "" );

>             RegDBSetKeyValueEx( szKey, "Template", REGDB_STRING, "good.tpl", -1 );

>             RegDBSetKeyValueEx( szKey, "TemplatePath", REGDB_STRING,

>                           svMainDirectory ^ "TEMPLATE", -1 );

>             if (bIncludeSamples) then

>                // Create "DEMOS" key

>                szKey = "SOFTWARE\\" + COMPANY_NAME + "\\" + PRODUCT_NAME + "\\" +

>                        PRODUCT_VERSION + "\\" + "DEMOS";

>                RegDBCreateKeyEx( szKey, "" );

>                szDemo    = svMainDirectory ^ "PROGRAM\\MULTI.DBD";

>                szProgram = svMainDirectory ^ "PROGRAM\\DEMO.EXE";

>                RegDBSetKeyValueEx( szKey, "path0", REGDB_STRING, szDemo, -1 );

>                RegDBSetKeyValueEx( szKey, "exe0", REGDB_STRING, szProgram, -1 );

>                RegDBSetKeyValueEx( szKey, "active0", REGDB_STRING, "Play", -1 );

>                szDemo    = svMainDirectory ^ "SAMPLES\\LAUNCHER.DBD";

>                szProgram = svMainDirectory ^ "PROGRAM\\DEMO.EXE";

>                RegDBSetKeyValueEx( szKey, "path1", REGDB_STRING, szDemo, -1 );

>                RegDBSetKeyValueEx( szKey, "exe1", REGDB_STRING, szProgram, -1 );

>                RegDBSetKeyValueEx( szKey, "active1", REGDB_STRING, "Play", -1 );

>                RegDBSetKeyValueEx( szKey, "exe2", REGDB_STRING, szProgram, -1 );

>                RegDBSetKeyValueEx( szKey, "active2", REGDB_STRING, "Play", -1 );

>                RegDBSetKeyValueEx( szKey, "exe3", REGDB_STRING, szProgram, -1 );

>                RegDBSetKeyValueEx( szKey, "active3", REGDB_STRING, "Play", -1 );

>                RegDBSetKeyValueEx( szKey, "exe4", REGDB_STRING, szProgram, -1 );

>                RegDBSetKeyValueEx( szKey, "active4", REGDB_STRING, "Play", -1 );

>                RegDBSetKeyValueEx( szKey, "exe5", REGDB_STRING, szProgram, -1 );

>                RegDBSetKeyValueEx( szKey, "active5", REGDB_STRING, "Play", -1 );

>                RegDBSetKeyValueEx( szKey, "exe6", REGDB_STRING, szProgram, -1 );

>                RegDBSetKeyValueEx( szKey, "active6", REGDB_STRING, "Play", -1 );

>                RegDBSetKeyValueEx( szKey, "exe7", REGDB_STRING, szProgram, -1 );

>                RegDBSetKeyValueEx( szKey, "active7", REGDB_STRING, "Play", -1 );

>                RegDBSetKeyValueEx( szKey, "exe8", REGDB_STRING, szProgram, -1 );

>                RegDBSetKeyValueEx( szKey, "active8", REGDB_STRING, "Play", -1 );

>                RegDBSetKeyValueEx( szKey, "exe9", REGDB_STRING, szProgram, -1 );

>                RegDBSetKeyValueEx( szKey, "active9", REGDB_STRING, "Play", -1 );

>             endif;

>             // Create "HELPMENU" key

>             szKey = "SOFTWARE\\" + COMPANY_NAME + "\\" + PRODUCT_NAME + "\\" +

>                     PRODUCT_VERSION + "\\" + "HELPMENU";

>             RegDBCreateKeyEx( szKey, "" );

>             RegDBSetKeyValueEx( szKey, "MaxNum", REGDB_NUMBER, "1", -1 );

>             RegDBSetKeyValueEx( szKey, "path0", REGDB_STRING, svMainDirectory ^

>                                               "README.TXT", -1 );

>             RegDBSetKeyValueEx( szKey, "exe0", REGDB_STRING, "NOTEPAD.EXE", -1 );

>             RegDBSetKeyValueEx( szKey, "active0", REGDB_STRING, "Read Me", -1 );

>     end;
> Even though SETUP.RUL is a long file (more than 500 lines), it's well-documented and logical. You should have little difficulty modifying this file to suit your purposes. The packing list file, shown in Listing 24.3, is much shorter. Like the SETUP.INS file, the packing list file must be processed (using the PACKLIST.EXE program) and placed on the first disk of your product's distribution disk set. Listing 24.3. PACK.LST: The packing list input file.
>     1;

>     ..\disk1\data.z
> In this example, the application's files will fit on a single disk, so there is only one source file for Setup to process. ### Using InstallSHIELD Professional The documentation from InstallShield Corporation refers to the InstallSHIELD Professional version as InstallSHIELD PE. This chapter uses the same designation. InstallSHIELD PE is very much an expanded version of InstallSHIELD SE. The Professional version covers more operating systems, including Windows 3.x, Windows 95, Windows NT, and OS/2. InstallSHIELD PE offers the following features: The capability to create a single installation system that includes Windows 3.1, Windows 32s, 32-bit Windows 95, and 32-bit Windows NT 3.5 A complete set of installation templates More than 50 built-in user interface objects and complete customization of all objects in InstallSHIELD PE The ability to integrate your own custom dialog boxes The InstallSHIELD Visual Debugger, a Windows hosted debugger designed specifically for installation building and testing The ability to use your company logo, corporate look, animated bitmaps, and billboards during installation The ability to selectively install components of a multicomponent application The capability for your installation program to launch help files, readme files, and other applications at any time during or after the installation process The capability to intelligently update or modify system files, AUTOEXEC.BAT and CONFIG.SYS, private and system .INI files, and the Windows Registry The capability to call any function in any DLL—including any Windows API—directly from the script If after using InstallSHIELD SE you find that you need a more powerful and flexible installation program, you can migrate to InstallSHIELD PE. The InstallSHIELD PE product is compatible with InstallSHIELD SE. This means that you can create a simple installation using InstallSHIELD SE, and, as your needs expand, you can easily migrate to InstallSHIELD PE. ### Modifying the CONFIG.SYS and AUTOEXEC.BAT Files You can incorporate Visual C++ binary file instructions and functions in your setup application to read the AUTOEXEC.BAT and CONFIG.SYS files on the recipient's fixed disk to determine whether you need to make modifications to these files so that your application will execute properly. If the user isn't running Windows for Workgroups, you must load SHARE.EXE in order for OLE 2.0, OLE Automation, and data access to operate properly. Thus, you might need to add a SHARE.EXE /L:500 entry to the AUTOEXEC.BAT file. (The parameter reserves DOS environment space for 500 locks, which is sufficient for most applications.) Your setup program must open and manipulate the AUTOEXEC.BAT and CONFIG.SYS files by reading and parsing them. It's important to realize that it's unacceptable to simply add more lines to the ends of these files. Your application must test to see whether the desired command or string is present and then add the string only if it's missing. This addition usually can be done at the end (or beginning) of the AUTOEXEC.BAT and CONFIG.SYS files, but not always. There are few cases with Windows 95 in which you need to work with either the CONFIG.SYS or AUTOEXEC.BAT files. With Windows 95, neither of these files needs to exist, and with Windows NT, neither of these files does exist. TIP Polite setup applications use a message box to advise the user that the AUTOEXEC.BAT and CONFIG.SYS files might need to be altered. Before making any changes to these files, save a copy of the original versions with the FileCopy instruction and advise the user of the names of the backup files. An even more polite approach is to offer the user the option of modifying the existing AUOTEXEC.BAT and CONFIG.SYS files or creating a new set of files that the user can inspect before copying over AUTOEXEC.BAT and CONFIG.SYS. ### The CD-ROM AutoPlay Facility Microsoft has added a new feature to Windows 95—the capability to have a program run whenever an AutoPlay-enabled CD is inserted into the CD-ROM drive. This enables software developers who distribute by (or execute from) CD-ROMs to have either the program or an installation routine start whenever the CD-ROM is inserted into the drive. The AutoPlay facility enables "Plug-n-Play" to extend into the software arena. Users benefit from a product that is easy to use. Using CDs under Windows 95 is easy. You can select the property page for a given CD-ROM by right-clicking on the CD in Explorer, as shown later in Figure 24.7. Many users (and developers) have decried the poor interface between CD-ROM-based applications and Windows. With applications created before AutoPlay, the user had to insert a CD-ROM into the drive and enter a command (often, but not always, called setup) to install the product. Many setup programs ran well, but the concept behind CD-ROM-based applications is that the application (and much of its static data) doesn't need to be copied to the computer's local hard disk; instead, it may remain on the CD-ROM. This permits the user to have a large library of CD-ROM-based applications without having to dedicate substantial portions of the hard disk to these CD-ROM applications. With AutoPlay, the following things happen when you insert a CD: AutoPlay-enabled CD-ROMs execute the designated program. This program typically either is a setup program (less optimal) or actually executes the CD-ROM's main program (more optimal). Audio CDs automatically play using the CD Player applet, which is a standard part of Windows 95. CD Player works very much like your home CD player and offers many of the options and features of a typical CD player. All other CD-ROMs behave as they do under Windows 3.x—that is, they do nothing special. Sometimes users won't want to activate a program (or play an audio CD) automatically. In this case, they can hold down the Shift key when the CD-ROM (or CD) is inserted to disable AutoPlay. This enables the user to perhaps simply do a directory of the CD-ROM, run a different program from the CD-ROM, or otherwise use the CD-ROM. NOTE People tend to believe that if they stick a CD into their computer, it won't have a virus, trojan horse, or other nasty surprise in store. However, it would be wise to treat most CDs with the same care you would give a diskette or a file downloaded from a BBS: Do a virus scan! NOTE One alternative would be for AutoPlay to display a dialog that gives the user one button to continue the AutoPlay process and another button to kill the process and continue with the task that had focus. With this technique, the user doesn't need to remember to press the Shift key. Microsoft also recommends this technique: A quick-loading splash screen that lets the user abort. #### Using the AUTORUN.INF Files To make AutoRun work, Windows 95 looks at the CD or CD-ROM that the user inserts. If it's an audio CD, the CD Player applet is launched and the CD is played. If the CD-ROM has an AUTORUN.INF file, this file is examined, and the actions specified in the AUTORUN.INF file are followed. (The AUTORUN.INF file is stored in the CD-ROM's root directory.) The minimum necessary AUTORUN.INF file is shown in Listing 24.4. Listing 24.4. The minimal AUTORUN.INF file for AutoRun compliance.
>     [autorun]

>     open=filename.exe

>     icon=filename.ico
> Even this minimal AUTORUN.INF file, with only three lines of information, can be expanded. Take a look at each of the options available and what you can use in your AUTORUN.INF files: open=: This line specifies which program is to be executed whenever the user inserts the CD. This program can reside in the same directory as AUTORUN.INF (the CD's root directory) or in any other directory. To specify a subdirectory, use the format
>     open=subdir1\subdir2\filename.exe
> - In this example, Windows 95 will search the CD's directory structure and insert the correct drive letter as necessary. When the program specified in the open= line is executed, the current directory isn't changed. Microsoft recommends that a "teaser" application be launched using the open= line. This teaser application might give the user an opportunity to execute the program or do an installation. A more complex teaser program might check to see whether the application has been installed and, if it has, launch the application rather than the installation program. icon=: The icon for the CD is contained in either an .ICO, .BMP, .EXE, or .DLL file. If the file contains more than one icon (the STARmanager application has a number of different icons), you could specify the icon using the following syntax:
>       icon=filename.exe,2
> In this example, you have specified that the third icon (the icons are zero-based) will be used. Unlike the open= expression, the icon= line doesn't let you use a path. To use a path, you should use the defaulticon= expression, which is discussed next. defaulticon=: The defaulticon= line specifies an icon path. This path is relative to the CD-ROM drive if no drive specification is provided. I strongly recommend that you not use a drive specification. You can't depend on finding any drive at a known location, nor can an application require drives to be at specific places. WARNING Don't code your programs to expect a C: drive to be present or writeable. There is no guarantee that a computer will have a C: drive, or that it will be accessible to applications. Diskless workstations might have drives that are found at different locations each time the system is started. You must take this into consideration when you're writing your application. When an AutoPlay-enabled CD is inserted into the CD-ROM drive, the user can right-click the CD's icon and get a menu of choices. If your AUTORUN.INF file has an open= line, the menu that Explorer displays includes the commands shown in Figure 24.7. Figure 24.7. An AutoPlay-enabled CD-ROM in Explorer. The AutoRun facility added the AutoPlay selection to the list of actions in the pop-up menu. If you add the following lines to your AUTORUN.INF file, a new menu item will be added to the menu with the text Item For Menu. When this menu item is selected, the program specified in the command line will be executed.
>     shell\verb\command=filename.exe

>     shell\verb=Item For Menu
> For example, to have the user check out a README file, you could add the following to the AUTORUN.INF file:
>     shell\readme\command=notepad readme.txt

>     shell\readme=Read &Me
> In this example, the user's menu will include a Read Me selection. When selected, it will execute the Notepad program, loading and displaying the README.TXT file. Normally, the default menu selection for an AutoPlay-enabled CD is AutoPlay (as shown in Figure 24.7). You can change this default by adding
>     shell=verb
> The shell= line specifies the action that will take place when the user selects the AutoPlay menu option. For example, to activate the readme selection, you could include the following lines in your AUTORUN.INF file:
>     shell=readme

>     shell\readme\command=notepad readme.txt

>     shell\readme=Read &Me
In this example, if the user selects AutoPlay from the menu, the README.TXT file will be loaded in Notepad. #### Suggestions for Creating AutoPlay CDs Microsoft has several suggestions for developers who are creating AutoPlay CDs. The most important is that the application that is launched automatically be small. For performance reasons, Microsoft recommends that you not try to load a large application whenever the CD is inserted. Instead, load the smaller teaser application, which will then let the user load the larger application. For CD-ROMs that contain only data and no executable program, the teaser program could simply display a README file. This lets the user quickly determine the CD-ROM's contents. For data CD-ROMs, be sure to date the data using a date format that is easily understood. Don't use summer/winter/spring/fall designators: these seasons mean different things to people in different parts of the world. Also, don't use "1Q" designators, because these terms aren't always meaningful to all users. Instead, use months and years, such as January 1995, to date data. Your README file should also indicate how often the data on the CD-ROM is updated. For example, for a database of company information that is updated on a quarterly basis, you will want to inform the user when the data has become "stale" so that he or she can get an update to the CD-ROM. Here is the potential for marketing upgrades to products that are prone to become obsolete. With applications in which the teaser or introduction program includes a button to let the user launch the full application, you can take advantage of Windows 95's multithreaded processes to begin the loading process. That way, if the user decides to start the application, you're one step ahead of the game and will be able to start the application (hopefully) without having to incur a long delay while the main program loads. Try to create applications that run well from CD-ROMs when possible. This lets the user better manage his or her hard disk. If you must install programs or other files on the hard disk, use a recognized installation program (such as the InstallSHIELD SDK program, mentioned earlier) to let the user easily uninstall the program from his or her hard disk. There's nothing worse than having a CD-ROM-based application create a directory that contains virtually everything that is on the CD-ROM. ### Demos and Shows It's always nice to be able to send a demo (either a working version or a canned demo, usually called a show) to a prospective purchaser. It's now possible to publish demos of your products using traditional techniques (such as either by itself or as part of a CD-ROM compilation) or using online publication techniques, including the Internet. #### Using DemoSHIELD There are a number of packages for creating demo programs. One such product is DemoSHIELD. It lets the developer create a professional demonstration of the product's capabilities without having to resort to low-level programming. Using DemoSHIELD is easy. The WIN32SDK has a working demo model of DemoSHIELD that you can use. This version of the product is limited to three panels, but even with this limitation, you can still examine the product and see its capabilities. #### Working Demos Many programmers distribute their applications using the "working demo" technique. This enables the potential user to use the application, get a feel for its weaknesses and strengths, and see how well the application fills his or her projected needs. There is a difference between a working demo and using shareware to distribute your application. A working demo is almost always a copy of a product and has some limitation, such as a disabled save function. There is no way for most working demo programs to be upgraded without the user being sent a new copy of the program, whereas shareware programs typically either are fully functional or can be upgraded to full functionality by the user when the application is registered. Distributing working demos and shareware applications is no different from distributing any other application. A smooth installation of the demo version goes a long way toward convincing a potential user to buy your product. A poor installation will convince users that your product is substandard, regardless of how well the application has been written. ### Summary Creating distribution disks is the final step in developing a Visual C++ database application, so it's fitting that this chapter closes this book. The objective of this book was to give DOS database developers and Visual C++ programmers who are new to database applications the background needed to create professional-grade database front ends with Visual C++. We hope this objective was accomplished. Visual C++ is reportedly Microsoft's most successful and profitable language product. Therefore, you can expect Microsoft to release a continuing series of upgrades to Visual C++. Fortunately for Visual C++ developers, Microsoft has given its highest development priority to ensuring the compatibility of new versions of Visual C++ with code written for prior versions. The remainder of this book consists of appendixes. Appendix A lists sources of add-on products and provides additional information for Visual C++ programmers. Appendix B lists the standard naming conventions for Visual C++ objects and variables. Appendix C gives you instructions for using the CD that comes with this book. Contact reference@earthweb.com with questions or comments. Copyright 1998 EarthWeb Inc., All rights reserved. PLEASE READ THE ACCEPTABLE USAGE STATEMENT. Copyright 1998 Macmillan Computer Publishing. All rights reserved. |