Automating the Build Process Using Macro Components and Prototyping

 

David Reed
Microsoft Corporation

July 23, 2003

Summary: Resolving dependencies in Target Designer can be time consuming and bothersome. Many XPe customers have asked for the ability to "script" or automate the build process. As it is impossible to automate the build process from the CMD prompt or through scripts, you can create custom components in Component Designer that will help you automate a great deal of your build process to reduce overall build time and achieve consistent results from build to build. (8 printed pages)

Build Images Using Macro Components

Building with macro components is by far the best and easiest way to start automating the build process. Macro components are easy to create and modify, and are an invaluable tool for the runtime builder. Macro components are custom components that simply link to other components in the database. Good examples of macro components are the Microsoft® Windows® XP Embedded Design Templates included in the component database, such as Home Gateway and Kiosk/Gaming Console.

Macro components link to other components and provide a starting point for creating embedded images. Using Components Designer, creating your own customized design templates to start the automation process is simple and easy.

Most of the runtime images I create are generated from a set of macro components. For example, I almost always import a TAP.exe-generated PMQ file into Component Designer to generate a hardware macro or hardware profile component that I can use again and again. Once I have finished creating my hardware macro, I import the SLD file into my database so I have access to my hardware profiles anytime I wish.

A very useful macro I frequently use is the Runtime Quick Start HelperMacro that was added to the component database for the SP1 release of XPe. This component can be found under the Software | Test & Development category in the component database. The quick start helper macro will add the most common component dependencies to your runtime image during the initial dependency check, thus reducing the overall build time of an image.

Create Your Own Helper Macros

It is simple to create your own version of the helper macro; here's how to do it. First start with your TAP imported hardware profile, and run a dependency check using auto resolve. As you resolve the dependencies required for your configuration, make a note of the components you choose for your image. For example, if you always require support for FAT, NTFS, and CDFS in your configuration, you should consider making a custom macro to include these components automatically for you.

Once you know what components you have selected for your image, you can use Component Designer to create a custom macro component that will include the components you desire in your configuration. Start Component Designer, create a new SLD file, and add a new component. On the Component Properties view of your new component, mark the component as a macro component in the check box at the bottom of the form. The component's name should appear in bold in the SLD browser window, to indicate that you are working with a macro component.

Next, you need to create links to the components you require in your configuration. To do this, you need to create Component Dependencies to the components in the database. You do this by right clicking on the Component or Group Dependency node of your macro component, and by then selecting Add | Component Dependency.

Now simply select the components you desire in your configuration from the available components in the database. Any Component Dependency you add to your macro will automatically add the specified component to your configuration during a dependency check.

Additionally, by specifying the Selector Prototype component as your macro's Prototype component, you inherit a free configurable DHTML script for your macro components in Target Designer.

So What Is Prototyping Anyway?

Prototyping is an inheritance model that XP Embedded uses extensively. Any component in the database can be used as a prototype for a new component. For example, if I were to set the Microsoft® Internet Explorer component as the prototype of my new custom component, I would inherit every aspect of Internet Explorer in my new component by default. That is, my new component would inherit the Group Memberships, Category placement, File and Registry Resources, Custom Resources, and even Component Dependencies of Internet Explorer. Then I can expand on Internet Explorer and add additional files, registry keys, and system resources to my customized version of Internet Explorer.

One of the main advantages of using prototyping is the ability to reuse or expand existing components, thus reducing the time and energy required to generate updated or customized components. It is also good to know that there is no limit to the prototype chain you can utilize, so it is up to the component author's creativity or need to define.

How Does Prototyping Work?

Adding components to an SLX configuration in Target Designer is called instantiating a component. Numerous activities occur when a component is instantiated in a SLX file. For example, component scripts may be executed and a number of additional actions may occur depending on the component's specific configuration and settings. Also, upon instantiation, prototype chains are "collapsed" into a single component or instance, with the top-level component's properties becoming the new default, thus overriding the original component's settings if there are differences.

Okay, so now we understand prototyping better, but how do users take advantage of this cool technology to help them automate this build process? The answer has been in Target Designer the whole time.

Start or open a configuration that includes the component User Interface Core in Target Designer. Click on the Settings node of the User Interface Core component, and enable the Shell features that you prefer in your configuration. When complete, navigate to the User Interface Core component's main properties node and click the Advanced button to view the Extended Properties of the component.

Here you can see the CMI methods of Windows XP Embedded for each of the selections you chose in the User Interface Core's DHTML settings. Make note of the options you selected, because I am going to show you how to use this information in a custom prototype component that will automatically enable these settings for you.

User Interface Core Settings

In my runtime, I selected the following options in my User Interface Core component:

Option Selection
Show My Computer on Start Menu Enable
Show My Documents on Start Menu  
Show My Recent Documents on Start Menu  
Show My Pictures on Start Menu  
Show My Music on Start Menu  
Show My Network Places on Start Menu  
Show Desktop icons  
Show Favorites on Start Menu  
Show Help and Support on Start Menu  
Show Control Panel on Start Menu Enable
Show Printers and Faxes on Start Menu  
Show Network Connections on Start Menu  
Show Search on Start Menu  
Show Run on Start Menu Enable
Show Log Off on Start Menu Enable
Show Shut Down on Start Menu Enable
Show Internet Explorer on Start menu  
Show Outlook Express on Start menu  
Show All Programs list on Start menu  
Show context menu on Shell folders Enable
Show context menu on Task bar Enable
Show Notifications on Task bar  
Lock Task bar Enable
Use Windows Classic folders Enable
Enable Drag and Drop on Start Menu Enable
Prohibit access to Control panel  
Prohibit access to Hot keys  
Number of programs on Start menu  

I don't need to worry about including the default settings in my custom version; they will be inherited by default. So I only need to include the modified settings I want in my configuration in the Extended Properties of my custom prototype component.

So now that I know the CMI methods I want to enable, I am ready to create my custom component in Component Designer. Open Component Designer, and create a new SLD file and add a new component. Give your new component a name, and fill in the component properties as you deem fit. (Leave Target Designer open for reference.)

Next, navigate to the Prototype field, and click the Browse button on the prototype field. Navigate to Software | System | User Interface | Shells | Window's Shells and select the User Interface Core (R1507) component as your prototype component.

The next and most important step is to add the CMI methods you gathered earlier to your new component. Return to your new component's Component Properties and click the Advanced button to enter the Extended Properties of your component. Here we simply create a new extended property for each of the CMI methods we want to include as a default setting.

For example:

Name Format Value
cmiShowControlPanel Boolean True
cmiShowRun Boolean True
cmiShowMyComputer Boolean True
cmiShowIE Boolean True
cmiShowTaskBarContext Boolean True
cmiShowFoldersContext Boolean True

We are almost done. You need to enable one check box on the Component Properties page of your new prototyped component. That is, we need to enable the Enable Multiple Instances check box for this specific component. Here's why: The User Interface Core component in the XPe database is a single instance component, meaning that only one instance of this component can exist in any given SLX configuration. So by flagging this component as multi-instance, it will collapse correctly and not throw any errors during a dependency check.

Note that though it is not always necessary to flag a prototyped component as multi-instance, it certainly doesn't hurt anything.

And just like that, we are done! Not too hard, just a bit new if this is your first time. In fact, the process I have just outlined can be used for any component in the database that has extended or configurable properties.

Components such as Administrator & User Account are also very easy to prototype; let's give it a try.

Administrator component:

Create a new SLD file and a new component. Set the prototype field to the Administrator component under Software | System | System Services | Base.

Add the following CMI Method in the Extended Properties of your new component:

cmiUserPassword   String   <your secret password goes here>

Enter the default password you want your administrator to have, mark the component as multi-instance, and you are done. Easy as pie.

User Account

User accounts are even easier, as they are natively multi-instance components.

Create a new SLD file and component. Set the Prototype to the User Account Component, which is found under Software | System | System Services | Base in the component database.

Add the following CMI Methods in the Advanced Properties:

CmiUserPassword   String   <your secret password goes here>
cmiUserName         String   <your unique user name goes here>
cmiUserGroup         Integer   3 (user level rights)

HAL Component—ACPI

The HAL components are just as easy to manipulate. For this example, I will enable pagefile support, set the default power schema for my device, and enable Hibernation support.

Name Format Value
CmiPagefileEnable Boolean True
cmiPagefileInitialSize Integer 100
CmiPagefileMaximumSize Integer 100
CmiCurrentPowerPolicy Integer 1
CmiHibernateEnable Boolean True

The HAL components are also responsible for setting the Computer Name and Registered Owner. These settings can also be preconfigured in a prototype if needed.

As you can see, any configurable component setting can be predefined in a custom prototype component.

Enable Multiple Instances

In order to get some prototype components to auto-resolve correctly, it is necessary to set the Enable Multiple Instances flag on the component's property page. This flag will allow single instance components, such as HAL components and User Interface Core to auto-resolve correctly during a dependency check.

If you do not enable this flag on your prototype components, Target Designer will be unable to resolve your prototyped components as the default component during a dependency check. This occurs on single instance prototyped components because when Target Designer tries to collapse the component chain, it finds that the parent component has the single instance flag enabled and cannot automatically resolve this issue.

By setting all prototype components you create as multi-instance, you can use auto-resolve and take full advantage of automation.

Creating Your Own Design Template

There is no need to use XPe in-box Design Templates if they do not meet all of your needs. Creating your own Design Templates is easy to do, and can be a big time saver for your project.

By using the existing Design Templates in the XPe database, you can simply jot down what components you require and create a custom macro that includes all of the components your image requires.

I often create what I call the "Master Macro" for my design template. I do this specifically if I am linking numerous components and macros I have created into one custom Design Template. I can link hardware macros (PMQ files I have imported in Component Designer) I have created, as well as my custom prototype components, into one easy to manage "Master Macro" component.

Working with Visibility

Visibility is a concept that is important to master in XP Embedded. So what is visibility all about? Visibility defines the level of granularity for a component. Each component has a level of visibility assigned to it, which represents how granular the component is in the grand scheme of things.

Most feature components, such as Internet Explorer and Microsoft® Media® Player 8.0, will have a visibility of 1000 in Target Designer, so users can easily locate them in the database. Many of the required but not user-configurable components in the database will have a lower visibility, and are not exposed to the user by default.

For example, the component Primitive: Browseui is required by Internet Explorer and should not have to be manually added to a configuration by users. Thus this component has a default visibility of 200.

You can select the visibility threshold to increase or decrease the number of components displayed through the Tools | Options | Advanced menu option in Target Designer. Most XPe users I meet tell others to drop Target Designer's visibility to 100 and leave it there. This is okay when you need to confirm that a specific component is included in your image, or if you are simply curious as to what exactly is in your configuration.

In my experience, however, the default visibility of 1000 is great for building images. It not only speeds up the build process because there are fewer components to display to the user, but component dependencies on granular components are automatically resolved and added to the configuration without the user needing to know about them.

There are some core components in the database that have a visibility lower than 100, which is below what Target Designer will allow for visibility. Most of these components are not configurable and thus are not exposed to the user. After more than two year of image building with the XPe tools, I have never needed to tweak or configure a component with a visibility lower than 100.

You can make visibility work for you by setting your custom "configurable" components to 1000 level visibility and setting non-configurable components to visibilities of 100 or 200 so you do not need to bother with them.

Warning About Prototyped Components

Because prototyped components inherit every aspect of the original component, users with prototyped components of core XPe components will notice that new component dependencies will show up during dependency checks. Users that normally select User Interface Core will now be displayed two options for this core component: the new prototyped component and the original User Interface Core component.

This situation is really unavoidable because fundamental to the prototyping process is inheritance of every aspect of the original component. If the original component had a hard dependency on Explorer.exe, the new prototyped component will as well. This dependency may interfere with the dependency checking with which you are familiar by including your new component in the list of components to resolve.

To combat this, I only use prototyped components of core XPe components in specific images and designs I am building. When I do not require prototyped components (or full automation), I remove the custom prototype components I have created from my database. I often use packages I have created to tie my custom prototyped components together. This allows me to easily remove whole suites of components from my database with little effort.

Nevertheless, if you, or your company, are working with a single image or design, prototyping is an invaluable method to ensure consistent results from build to build. By combining prototyped components with macro components, an entire build can be as easy to generate as pressing check dependencies (F5 hot key) once.

 

Get Embedded

David Reed is a Program Manager on the Windows XP Embedded team. His current responsibilities are to work directly with key Microsoft Partners through the XP Embedded Joint Development Program (JDP). His past responsibilities included being the software test engineer in charge of the Component Designer tool for the first release of XP Embedded, and then as a runtime builder & test engineer in charge of the CoreOS & FBA testing effort for the SP1 release of XP Embedded.