Creating OEM Preinstall-Friendly Applications for New Windows-Based PCs

Peter Denniston
Microsoft Corporation Technology Brief (version 2.0)

Created: February 1996
Revised: May 1996

Abstract

Original equipment manufacturers (OEMs) represent a potentially large revenue stream for application software development companies willing to sell software directly on the OEMs' PCs rather than through standard retail software delivery mechanisms. OEMs typically preinstall a wide variety of application software on new PCs before shipping them to end users. Although OEMs can use application setup programs designed for end users in the manufacturing facilities, OEMs strongly prefer programs designed to accommodate their factory preinstallation needs.

This technical paper provides information to help application software developers design setup applications so that OEMs can easily preinstall their programs when installing the Microsoft® Windows® 95 operating system in a factory environment.

Silent Script-Based Setup

The key to successful OEM preinstallation of an application is developing a silent, script-based setup program that runs without user input. Examples of Microsoft® Windows®-based application setup programs that support silent setup scripts are MSSETUP (on the Microsoft Win32® SDK), InstallShield (a third-party application), and ACME (a Microsoft-only program used to install many Microsoft applications, such as Microsoft Office).

The script for silent setup must support three distinct phases of Windows setup:

This separation of setup functions gives OEMs the flexibility they need in their manufacturing environment to accommodate their unique factory constraints. You can put all these functions for application setup into one script, if each function can be processed at different times as determined by the OEM. The setup script(s) must also support pre-definition of all the choices that an end user would typically make when installing the application.

Phase 1: Copying Non-PC-Specific Application Setup Files to the Post-Setup Directory Structure

The non-PC-specific setup phase involves having your setup script place all the non-PC-specific files in a tree structure that matches their post-setup locations and all PC-specific files or installation-related files in a structure that allows them to be set up at a later point in the install process. The goal of this phase is to perform as many non-PC-specific setup steps as possible on a single PC so that non-PC-specific tasks do not have to be run on every newly manufactured PC.

Important   For script actions during the non-PC-specific setup phase, do not assume that the directory structure your application setup program creates is on the PC that will ultimately be running these files. In most cases, the OEM will run this phase on an engineering workstation and transfer the resulting directory structure to a network "reference server" for downloading or to a "reference hard drive" for duplication. Newly manufactured PCs connect to this "reference server" to download the Windows 95–based software and any applications the OEM has set up; in other manufacturing environments, the new PCs receive duplicates of the "reference hard drive." The actual method used depends on the OEM.

The structure you provide should be capable of being placed correctly on a PC using the Xcopy command. Therefore, you should provide a method for the OEM to specify the root of this tree structure. The OEM will assume that this tree structure is merged into the preinstallation reference structure.

For example, for an application called FunDraw, the structure might be similar to the following:

FUNDRAW\ROOT\

         \FUN_DRAW

         XXXXX.XXX

            XXXXX.XXX

            XXXXX.XXX

         \TUTORIAL

            XXXXX.XXX   

            XXXXX.XXX   

         \SAMPLES

            XXXXX.XXX   

         \WINDOWS

            XXXXX.XXX   

            \SYSTEM

               XXXXX.XXX   

               XXXXX.XXX   

Important   Do not put any common system files in this directory (for example, Autoexec.bat, Win.ini, Vbrun100.dll). Changes and replacements to common system files must occur after Phase 1.

Phase 2: Copying PC-Specific Application Files to the Post-Setup Directory Structure and Applying Registry Changes

There are a number of tasks your setup program can only perform on the PC that will ultimately run the application software. Examples include:

Phase 2 is responsible for making all PC-specific changes to the new PC that do not involve end-user input. These changes are made on the new PC (rather than on an engineering workstation or the reference server). For a PC with Windows 95 preinstalled on it, your script can always assume the files will be installed on the C drive and the Windows directory is named "Windows." The drive and the directory name are hard-coded to these values in the preinstallation process.

If OEMs use disk duplication equipment to duplicate a master hard drive to multiple hard drives, they must run Phase 2 after duplication has occurred to ensure that the LFN settings you make during this phase are preserved. Many types of disk duplication equipment do not recognize LFNs and will destroy them in the process of the disk duplication.

We strongly recommend that you create a Windows INF file to accomplish Phase 2. Windows INF files can easily perform copy and delete operations, registry changes, and LFN creation. Also, using INF files provides the added benefit that your setup script can take advantage of SETUPX's DLL version checking for free. This helps ensure that you do not accidentally overwrite a newer DLL on the system with an older one that you are providing.

OEMs are given tools that can process sections within an INF file.

If your application has hardware dependencies, you should consider providing separate sections for each potential device in the Phase 2 script to make it clear to the OEM what you are doing. For example, if the OEM ships an S3 video chip on the motherboard, you could have an [S3] section in your INF that contains the lines necessary to copy some advanced drivers you provide, make registry changes, and so on.

Common and device-specific registry entries must be applied after Phase 1. However, your setup program does not need to distinguish between common and device-specific registry entries. Please notice the distinction between common and device-specific file copies and common and device-specific registry entries: common and device-specific file copies can be done during Phase 1, while common and device-specific registry changes must be done after Phase 1.

We also recommend that you create a link on the Start menu to a programs folder that contains the user install script used in Phase 3, as described later in this paper. Ideally, the link should be in the location where your applications will be placed at the end-user site.

Your installation program should add an icon for your primary application on the Start menu. Although your installation program can still create a "Program Group" in the Programs folder by using dynamic data exchange (DDE) as used in Windows version 3.1, this is no longer the preferred method.

To add an icon to the Start menu, your installation program should create a link to your application's executable file and place the link in the directory named \Windows\Startmen\Programs. (Notice that the Windows directory should actually be the path returned by the GetWindowsDirectory function.) An installation program can create a link by using the IShellLink interface. (For additional information about the IShellLink interface, see both of the following: MSDN Library, SDKs, Win32 SDK, Win32 Programmer's Reference, Overviews; and MSDN Library, Books and Periodicals, Programming the Windows 95 User Interface.)

Note   Your install script in Phase 3 is also responsible for deleting the original install link and creating any additional links to the post-user install paths needed for your programs.

Phase 3: Prompting for User Input, Application Auditing, and Final Processing

The final phase must run at the end-user site, because this phase allows for input of setup information that can only be provided by the end user, such as User Name entries. With OEM-preinstalled applications, these questions should be asked only when the application is launched, or they should not be asked at all.

Examples of items that might fall into this phase:

The reason for not asking these questions until the end user first runs your application is that the preinstalled PC might pass through a number of hands before it reaches the final customer. If you ask the questions automatically when Windows loads, the person who sees these questions might not be the person you intended to see them.

You should also strongly consider providing a mechanism to "audit" or bypass the end-user entries for your application. OEMs want to test your application on the new PC before it leaves the factory to ensure it will work correctly for the end user or to customize it. Resellers might want to demo your application on the new PC to potential customers.

In a similar vein, we provide auditing capabilities in the Windows 95–based product. Specifically, this feature allows the OEM or reseller to temporarily bypass the User Name and Company Name screen, Certificate of Authenticity screen, and End User License Agreement entry screen in Windows setup so that the OEM can test the PC without being required to enter a response.

For application auditing, we recommend that you allow the end-user-specific questions to be bypassed five times without requiring an entry. The method for bypassing these screens (either no check or a keystroke sequence) should not be obvious and should be documented only for the OEMs. If your application binds user information into the application executable, you should not be concerned about the fact that application auditing allows you to run in an unbound state. Binding will still occur—it just occurs the fifth time the application is run.

How OEMs Will Use Your New Application Setup Scripts in Their Preinstallation Process

In Windows 95 OEM Service Release #2 (scheduled to be released in August 1996), OEMs have access to a tool called the OEM Preinstallation Wizard (Opkwiz.exe). Among other things, this tool does the following:

The following shows a sample of the Opkwiz interface that OEMs will use to run these programs:

Figure 1. Sample Opkwiz interface

If you provide a script or set of scripts that meet the guidelines of this article, an OEM will install your application in the following manner:

Changing the Registry with INF Files

The Windows 95 registry provides a unified database for storing system and application configuration data in a hierarchical form. There are two different ways to edit the registry: modifying INF script files and using the Registry editor (Regedit.exe). INF script files are more powerful and correspondingly more complex than the registry import/export files created by Regedit. These scripts can be processed in the factory or at the end-user site.

Registry import/export files can be imported silently at either the factory or the end-user site in MS-DOS mode using a batch file or through the graphical interface of the Regedit tool. Your choice of whether to use INF scripts or registry export files for your application depends on your familiarity with these tools and the complexity of the changes your application needs to make to the registry.

Windows INF files provide a number of functions to manipulate INIs, files, and the registry. (For a complete description of INF files, see the MSDN Library, Product Documentation, SDKs, Windows Resource Kits, Windows 95 Resource Kit, Part 8 Appendixes, Appendix C Windows 95 INF Files.)

Registry keys are similar to a folder on a hard disk; they represent a sublevel in a hierarchy. Each key can have values and keys within it. Values are similar to files on a hard disk; they represent actual data. The value label is like a filename, and the value itself is like the file contents. The one exception is that one registry value in each key can exist without a label.

Adding and Replacing Values and Keys in INF Files

Registry additions and changes are invoked by placing an AddReg command in an [install] section of the INF and then listing one or more section names after it. The sections listed should exist and must have the following format:

Reg-Root_String, [subkey], [value-name], [Flag], [value]

This line can be used to create the subkey, set the value, or do both. If the key does not exist, it will be created.

Valid values for Reg-Root_string are the following:

Reg-Root string Meaning
HKCU HKEY_CURRENT_USER
HKLM HKEY_LOCAL_MACHINE
HKU HKEY_USERS
HKR Relative key for use by the class installer only

Valid values for subkeys are of the form key1\key2\key3, and so forth. A value-name is optional, if you need to set the value to the subkey itself. For the string (SZ) type, if the value is left empty, the subkey or value-name is set to a NULL string.

The flag indicates what kind of operation to perform. The valid values are the following:

Flag Meaning
1 Binary value and Replace key, if it exists
2 String value and Do Not Replace key, if it exists
3 Binary value and Do Not Replace key, if it exists

The subkey, value-name, and value all can use replaceable string keys of the form %strkey%, where strkey is a key specifying a string in the [Strings] section of the INF file. To use a % character in the line, use %% in this string.

Removing Values and Keys

Registry deletions are invoked by placing a DelReg command in an [install] section of the INF with a list of one or more section names as the value. The sections listed should exist and must have the following format:

Reg-Root_String, subkey, [value-name]

These field names have the same meaning as defined earlier in this section. If no value-name is provided, the entire key is deleted.

Defining DWORD Values

It is not possible to create a value of type DWORD in the registry with the INF registry operations. However, most users of DWORD values will accept a 4-byte binary value in its place. Remember that a binary representation of a DWORD is stored in little-endian format. For example, the value 12345678 (hex) is stored as 78, 56, 34, 12 (hex), and must be entered that way in INF files.

The following Sample.inf shows the addition and deletion of some imaginary registry items in an INF file.

SAMPLE.INF
; Test is the install section that is provided to start the operations.
; For example, in PISETUP.INF, [INFInstall] section, a line might read 
; "SAMPLE.INF, Test".
[Test]
AddReg = test.add, run.add
DelReg = wall.del

; Add TestDescription, TestName, and the test flags of 001100ffh to 
; the Software\testing branch of the registry.
[test.add]
HKLM, Software\Testing, "TestDescription",, "%Test_Desc%"
HKLM, Software\Testing, "TestName",,"INFTEST"
HKLM, Software\Testing, "TestFlag",1,ff,00,11,00

; Add the TESTAPP.EXE to the RUNONCE list.
[run.add]
HKLM, %KEY_RUNONCE%, "test",,"TESTAPP.EXE"

; Remove the current wallpaper.
[wall.del]
HKCU, "Control Panel\Desktop, "WallPaper"
HKCU, "Control Panel\Desktop, "TileWallPaper"

; Strings used in replacements above
[Strings]
Test_Desc="Test Description"
KEY_RUNONCE="Software\Microsoft\Windows\CurrentVersion\Runonce"

Creating Script Entries with Regedit

Regedit.exe includes an export feature that allows you to save all or part of the registry to a .Reg file. The .Reg files you create can be imported to any registry either through the GUI-based Regedit interface or silently using the /s switch with the regedit command. The syntax for the silent-based method is the following:

Regedit foo.reg /s

The simplest way to create a .Reg file is to export the branch using the GUI-based Regedit.exe utility in Windows 95.

To export a Registry branch using GUI-based Regedit:

  1. Click the Start button, choose Run, type Regedit and press enter.

    When Regedit starts, it displays a hierarchical tree that represents the registry.

  2. Use the mouse to expand each branch until you find the branch you want.

  3. From the Registry menu, click Export Registry File.

  4. Click Selected Branch and specify an Export Range. Then click OK.

After a file is in .Reg format, you can edit it to specify the value you want to define for the key set. Then you can apply the .Reg file using either the GUI-based or real-mode Regedit.

Notice that the .Reg file that is exported might contain keys you do not want to change. In this case, remove the lines you do not want from the .Reg file.

Regedit supports "add/overwrite" functionality in silent mode, not delete functionality. You cannot delete sections from the registry with silent mode Regedit, because the text file is essentially overlaid over the current contents of the registry.

The overwrite function only affects a single line in the registry; it will not overwrite the whole branch. To better understand the "add/overwrite" functionality of the silent-mode Regedit utility, consider the following example:

  1. Export all or part of the registry to a text file.

  2. Edit the file with a text editor:

    a.  Completely remove a key or value.

    b.  Modify another key or value.

  3. Use Regedit to read the values back into the Registry.

The net results of these actions are the following:

Specific Items to Consider for Preinstallation

Instruct the OEM on how to run your setup program. You own the responsibility for instructing the OEMs on how to execute each of the above phases in the context of your application setup program.

Make sure your setup program does not reboot the system. Your application setup program should not generate a reboot. If your application needs to trigger a reboot, tell the OEM to add a -b switch to the Runonce manager wrapper in the registry. Notice that this is only relevant to Phase 3, because Phase 3 is the only phase ensured to run on the target PC.

Path: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Runonce
Value name: Wrapper
Value data: Runonce.exe -b

The reason you do not want your application setup program to generate a reboot during Runonce independently of the -b option is that a reboot caused by your application will cause failures on the new OEM PC at a later time. Runonce is controlled by a program called the Runonce Manager (or referred to simply as "the wrapper," because it wraps itself around all the programs it runs and presents them in a list designed to make the items appear as though they are all being set up uniformly).

The wrapper controls the items that are run during Runonce, but it doesn't actually remove the items until after the successful completion of the last item. If your application bypasses the normal Runonce routine by causing a system reboot, the Runonce items will not be deleted and will remain in Runonce until a new application that uses the Runonce key reinstalls the wrapper; then all Runonce items from this setup will be re-executed.

Manage localized files and directories properly. It is not uncommon for OEMs to ship several different language versions of an operating system and applications on a new PC and then have the end user select the primary language during the first boot of the new PC. Some OEMs delete the other languages automatically after the user has made the language selection, while others allow the user to keep multiple language versions on the hard drive.

You should be aware that localized naming conventions for file and directory names in the localized versions of your applications can make things difficult for OEMs. Try to avoid using localized names wherever possible. For example, if your setup program is called Setup.exe in English and Installer.exe in French, the OEM will have to write a batch file that recognizes all the different variants of the filename for each language and calls the appropriate file for Phase 3.

In the context of another filename, the OEM might also need to make changes to the registry entries that occur in Phase 2 to get them to work properly. These inconveniences might seem minor to you, but they represent additional unnecessary work for the OEM.

A more significant example of where localized naming conventions can cause difficulty for OEMs is the case where directory names are localized. Localizing your directory names impacts both where the files are copied in Phase 1 and the path locations for the registry entries and end-user-specific entries in Phase 2. As with the localized file case listed above, the OEM can work around these with some effort.

Three logistical limitations with localized file and directory names cause OEMs grief:

  1. Some of the extended characters used in localized text appear differently under the MS-DOS® operating system than they do in Windows (because the character sets are different). Therefore, if the OEM creates any workarounds for localized issues, care must be taken to ensure the correct extended character is being used in the correct context. For example, if the workaround is Windows-based, it needs to use the correct extended character from the Windows code page for that language; if the workaround is MS-DOS-based, it needs to use the correct extended character from the MS-DOS code page for that language.

  2. If your localization team makes a localization mistake in even one language, the OEM has to workaround that mistake as if it happened in all languages. Because you were inconsistent in one language, the OEM has to develop a workaround that assumes you might be inconsistent in that area in another language.

  3. If the OEM develops a tutorial or printed material that refers to your application and it mentions files or directory names you use and have localized, the OEM will have to change the file and directory names in that tutorial code or printed material every time you localize.

The only appropriate place for localized directory names is where they are displayed in the UI to a user (for example, folders under the Microsoft Internet Explorer Favorite's folder).

Managing Long Filenames for Preinstallation

Your application setup program should not establish links on the desktop or create long filenames (LFNs) during an OEM preinstallation unless it is in Phase 3. When files are moved between the OEM's reference server and the target PCs in the factory, or when the OEM uses disk duplication equipment or older disk and archival utilities, the LFNs will not be retained.

The simplest way to avoid the loss of long filenames is to transfer the files to the target PCs as short filenames and then convert them to LFNs once they are on the target PC. This section describes how to convert to LFNs on the target PC using the registry, the Group Converter utility (Grpconv.exe), and the Runonce registry key.

Renaming Files with Grpconv

The Grpconv tool is designed to perform a number of LFN-related functions from a list of commands stored in the registry and in an INI file built on the fly (Setup.ini). One of these operations is renaming files. The following explains the registry entries required to add new rename commands for Grpconv to process.

Note   Grpconv can also build links on the Start menu and Desktop, and can remove files. Grpconv is added to the Runonce Enduser list by the OEM preinstallation configuration program. The OEM can run Grpconv earlier in the preinstallation process (for example, Runonce AUDIT or Runonce FACTORY) if Windows 95 is booted at least once on the new PCs in the factory.

Many OEMs do not boot Windows 95 in the factory; however, they do install a generic Windows 95 image on new PCs with no hardware detection performed, and then hardware detection and device installation are run at the end-user site.

The root branch of the registry for rename operations is the following:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RenameFiles

Each group of rename operations is added to a subkey under this branch. Each group of operations is limited to renaming files in a single subdirectory. A minimum of two entries must be made in each subkey to affect a rename: first, the directory path for the files to be renamed; second, the actual rename operation.

The first key in each group of operations is the directory entry. Each entry for a rename operation in the related directory is an entry of this form:

"old_short_name"="new_long_name"

The following example shows the contents of a registry export file that renames Oldname.txt to NewLongName.txt in the C:\Samples directory:

[HKEY_LOCAL\MACHINE\Software Microsoft\Windows\CurrentVersion\RenameFiles\Test]
@="C:\SAMPLES"
"OLDNAME.TXT"="NewLongName.TXT"

After Grpconv has processed a rename operation, it removes the entry from the registry. When Grpconv has completed a group of renames, it removes the subkey from the registry.

Grpconv.exe deletes the destination file before performing the rename. If the same rename operation is queued twice, it could result in a loss of the file. For example, suppose there is a bitmap that needs to be renamed from Picture.bmp to "Really Cool 3D Picture.bmp." The second time such a rename operation is performed, "Really Cool 3D Picture.bmp" already exists, so Grpconv.exe deletes it before performing the rename operation. The exception to this rule is when the existing destination filename is a directory.

Managing Long Names and Generated Short Names

Each long filename has a short filename associated with it. The file can be accessed with either name. However, the short filename depends on other files in the same directory, because Windows must make it unique. When a file is renamed from a short name to a long name, a new short name is generated. If the first new short name that Windows generates is the same as the original short name, then Windows will change the short name.

For example, renaming "Longfi~1" to "Long Filename" would result in Windows generating "Longfi~1" as the new short name. Because this conflicts with a name that already exists, Windows adjusts the new short name to Longfi~2 and then completes the rename. To avoid this, it is necessary to rename to a temporary filename and then to the final name. In most cases, a change in the short name will not matter unless the name is referenced elsewhere. For example, "Progra~1" (the Program Files directory) is referenced in multiple locations throughout the registry. Changing the short name could have negative consequences in several areas of the product.

The following INF code for the [bitmaps] section instructs Grpconv to give some bitmap files long filenames.

[bitmaps]
AddReg = winbmps.addreg

[winbmps.addreg]
HKLM,%KEY_RENAME%\BMPs,,,"C:\BITMAPS"
HKLM,%KEY_RENAME%\BMPs,"FLOWER.BMP",,"Rose Garden.BMP"
HKLM,%KEY_RENAME%\BMPs,"SPCSHUT.BMP",,"Space Shuttle.BMP"

[Strings]
KEY_RENAME = "Software\Microsoft\Windows\CurrentVersion\RenameFiles"