Export (0) Print
Expand All

Packaging & Building Software Factories – Part 1, Packaging with Visual Studio 2005

 

Authors:

    Jezz Santos (Microsoft)
    Edward Bakker (LogicaCMG)

Contributors:

    Rene Schrieken (LogicaCMG)

Reviewers:

    Attila Hajdrik (Microsoft)
    Gareth Jones (Microsoft)
    Pablo Galiano (Clarius Consulting)

October 2007

Applies To:

    .NET Framework 2.0
    Visual Studio 2005
    Visual Studio SDK 4.0
    Guidance Automation Extensions/Toolkit 1.2

Summary: One of the most challenging parts of creating an installer for a software factory solution is knowing exactly what dependencies, components, and configuration need to be installed to a target machine. For the types of package project types (VSX, GAT and DSL) involved in software factory solutions today, this information is neither obvious to derive nor trivial to implement.

Get the reference implementation.

Download the Reference Implementation for this article. You can use this as an example in your own organization. Please read the EULA before using this reference.

Contents

Introduction
Packaging Software Factories
GAT Packages
DSL Packages
Combining Components into Single Package
Creating a Combined Software Factory Installer
Summary
About the Authors

Introduction

Welcome to part 1 of a short series on packaging Software Factories solutions with Visual Studio 2005 and implementing a team build for Software Factories using Team Foundation Server.

Creating software factory solutions today, on the Microsoft development platform, typically involves the combination of one or more Guidance Automation Toolkit (GAT) guidance packages, and one or more Domain Specific Language (DSL) packages. Often these packages are supplemented with other components and customizations of Visual Studio Extensibility (VSX) in a VSX package, including: tool-windows, editors, commands, services etc.

Ideally, the deployment of any software factory solution would be within a single installer (MSI) containing all GAT guidance packages, DSL’s and VSX packages containing the extensibility code and components. Although each authoring toolkit (such as: GAT and DSL) offers a means of creating a setup project exclusively for that individual package, there is no easy and integrated way of combining multiple GAT and DSL packages into one combined setup project, containing the required information to deploy these combined packages as a single software factory release.

GAT and DSL package projects types both provide source artifacts (recipe manifests and definition models) that require intermediate parsing/compilation/registration steps before design-time development changes take effect in the executables they produce at runtime. In the case of GAT, a special registration process parses a package XML manifest file, and compiles and registers the recipes and templates to be used by the Guidance Automation eXtensions (GAX) runtime. In the case of a DSL, the DSL model definition requires transformation of its text templates into source code files which are then compiled into an assembly and registered with Visual Studio for runtime execution. Both these quite unique intermediate ‘pre-compilation’ steps require deliberate and manual intervention steps from the developers creating these package types. This is acceptable for individually managed development projects. But neither pre-compilation step is enforced as part of a check-in process or as part of the build process. In managed team development scenarios, these pre-compilation steps will need to be explicitly invoked to verify and ensure that resulting compiled executables reflect the current design-time changes in the intermediate artifacts, so that they don’t break builds, and that can be deployed.

This series provides information and guidance, for those implementing software factory solutions today, that addresses both packaging software factories into MSI installers, and implementation of team build environments for these types of solutions. Part 1 in this series, this part, addresses the creation of installers using Visual Studio 2005. The second part in the series addresses the implementation of team build of these solutions using Team Foundation Server.

Packaging Software Factories

The recommended way to package and deploy a software factory solution, like any other solution, is via an MSI installer. MSI is the preferred way to install, maintain and remove software from a windows computer.

Standard VS Setup Projects

With Visual Studio, MSI installers to meet the needs of most solutions can be created using standard Visual Studio setup projects. Although other MSI building products are readily available on the market for catering to more advanced installer needs (e.g. InstallShield and Wise etc.), standard VS setup projects provide most, if not all, basic capabilities for packaging most software factory solutions.

Creating a setup project to define an installer in Visual Studio is simply a matter of adding a standard VS setup project to your solution and then configuring the installer using its various editors.

Click here for larger image

This project type provides a friendly graphical user interface for configuring the installer, with various editors to configure the basic options. The capabilities of this setup project are limited to a basic set of capabilities of MSI for ease of use.

However, configuration of the editors and features of the setup project cannot be easily automated or extended, and the file format which the setup project uses is in a very difficult format to edit and modify with tools. Furthermore, as we will see in the second part of this series, this type of setup project cannot be built in a team build scenario using Team Foundation Server (TFS) because the project file is not MSBUILD compatible, and will be ignored by MSBUILD.

WIX Setup Projects

An alternative technology which can be used to create installer projects is Windows Installer XML (WIX). WIX is a free Microsoft open-source technology for building MSI’s just from XML files. The XML files used by WIX define the contents of the installer package.  The WIX toolset provides a WIX compiler (candle.exe and light.exe) to create your MSI from these files. WIX provides a number of tools in its toolset to compile the WIX XML files into an MSI. The WIX toolset also provides additional tools (such as: dark.exe) to reverse engineer existing MSI’s into WIX XML.

WIX files can be authored using any XML editor. WIX setup projects for Visual Studio are provided by 3rd party tools such as WIX Votive.

Click here for larger image

At the time of writing, the WIX toolset and WIX Votive are available in version 2.0 and version 3.0.

·         WIX Votive 2.0 uses non-MSBUILD compatible setup project files which cannot be built in an automated build environment such as Team Foundation Server.

·         WIX Votive 3.0 does use MSBUILD compatible setup project files suitable for automated build processes, but is considered still under development and unstable.

To work around these issues, an alternative project type is defined later in the document that uses WIX 2.0 with MSBUILD compatible project files to leverage the WIX toolset.

The advantage of using WIX over using the standard VS setup project are that: you have a much finer granularity of control over the created installer because WIX accommodates more features of MSI, and you can automate and script the creation and modification of WIX XML files with other tools. However, creating and editing these XML files by hand is very tedious, and there is little graphical user interface provided by tools like Votive to assist you to do more easily and more reliably.

WixEdit.exe is a 3rd party graphical WIX editing tool, which improves the manual editing of WIX XML files. However at the time of writing, this tool was still under development.

Orca.exe, an MSI editing tool, available as part of the Microsoft Platform SDK, used for customizing and validating existing compiled MSI’s.

The net result, whether using standard VS setup projects or WIX projects, is that either of these tools and their technologies provides a means to author a setup project to create and installer for your software factory solution. Furthermore, either of these tools can be used to package individual project types or combine several project types together as one installer.

MSI Installers

Before we delve into what the various software factory package types are that we are building installers for, and how we build those installers, let’s have a quick look at how we define an installer and its base components used in the setup projects.

An MSI setup project defines an installer in terms of the following primary components:

·         Registry Searches

·         Launch Conditions

·         Files

·         Registry Settings

·         Custom Actions

An MSI setup project also defines other components such as a user interface wizard and component features. But for the purposes of this article we are going to only address the above primary components, as these are the ones that vary the most between any deployed installer for a software factory.

Registry Searches

A ‘registry search’ is executed at the start of the installer to gather information from the target machine’s registry. This information is then assigned to property variables which are made available to other components in the installer for defining things like: files and folder names, parameters to custom actions etc.

A registry search is defined by specifying: a registry hive, key path, and value, and this value is then assigned to a named property variable. For example:

Name

Property Name

Registry Root

Registry Key

Value

Visual Studio Environment

VS2005ENV

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS

EnvironmentDirectory

If a registry search does not find the specified registry value on the target machine, its result is invalid, and this can be tested for by other MSI components.

Launch Conditions

A ‘launch condition’ is executed at the start of the installer to verify certain pre-conditions of the installer’s execution. Typically, launch conditions are used to ensure certain pre-requisite components are already installed on the target machine prior to execution of this installer. If a launch condition fails, the installer is halted, the user is informed of which condition was not met, and then the installer is terminated.

Launch conditions typically test for valid values of registry searches.

Launch conditions can also test ‘File Searches’. File searches are not described in this article.

A launch condition is defined by specifying a registry or file search condition to test, and a message to display to the user if that test fails. For example:

Name

Condition Name

Install URL

Visual Studio 2005

VS2005ENV

http://msdn.microsoft.com/vstudio/

Typically, the message displayed will declare that a pre-requisite component does not exist on the target machine and that that component needs to be installed before this installer can be run. Typically, this message will also include a URL to where the pre-requisite component can be downloaded or acquired from.

Files & Folders

Files and folders represent one of the basic units of physical assets that are installed to a target machine by the installer (registry settings being the other). An installer typically defines the location of the files to be installed, and folders are created as required. Files include assemblies, configuration files, resource files, shortcuts etc. Folders include: the user’s or machines programs menu, program files folders, application and machine data folders and the global assembly cache.

A file is defined by specifying the destination folder, filename and other file attributes. Folders are assigned a property variable for easy referencing by files. For example:

Folder Name

Property

Location

Always Create

Public Assemblies

PUBLICASSEMBLIES

[VS2005ENV]PublicAssemblies

True

 

File

Target

Package Assembly

[TARGETDIR]

Installer Assembly

[PUBLICASSEMBLIES]

Folder locations and file names can use property variables assigned by registry searches or calculated and provided by the installer from the target machines environment.

For a list of common property variables see the online MSI documentation.

Registry Settings

Registry settings define the other physical asset type that is typically installed to a target machine by the installer. An installer defines the registry hive, key and value to assign.

A registry setting is defined by specifying the registry hive, key, value type and value. For example:

Key

Sub Key

String Entry

Value

HKEY_CLASSES_ROOT

 

 

 

 

SOFTWARE\[Manufacturer]\[ProductName]

(default)

My Package Name

 

SOFTWARE\[Manufacturer]\[ProductName]

InstallDir

[TARGETDIR]

Registry key name and values can use property variables assigned by registry searches or calculated and provided by the installer from the target machines environment.

For a list of common property variables see the online MSI documentation.

Custom Actions

Custom Actions define actions or tasks that need to be executed in addition to executing launch conditions, installing files, folders and registry settings. Custom actions can be executed at various stages throughout the installation and un-installation processes. Typically, custom actions are used to execute scripts that run at the end of the installer. (e.g. launch a readme file, invoke an application, execute additional configuration or tools etc.)

For a list of common custom actions see the online MSI documentation.

Custom actions are typically implemented using scripts. The standard VS setup project however defines a mechanism that allows the installer developer to provide custom actions in an Installer Class as part of the solution they are deploying. This mechanism then provides the necessary hooks into the MSI custom actions engine to execute the installer class code at the right stage.

Installer classes do require that the code is installed on the target machine, and that it can be executed at install time by the installer.

Other setup project technologies, such as WIX, are able to implement custom actions using scripting mechanisms to avoid the trappings of installer classes.

A custom action is defined by specifying an installer stage to execute the action, and a script or installer class to execute. For example:

Stage

Script

 

Install

[VS2005EXE] /setup

 

Uninstall

[VS2005EXE] /setup

 

Scripts can use property variables assigned by registry searches or calculated and provided by the installer from the target machines environment. When using installer classes, these property values are passes using ‘Custom Action Data’.

Factory Package Types

Building software factories today, commonly involves the creation of templates and recipes defined in GAT guidance packages as a starting point. This is clearly evident in the early generation of the ‘1GAXPAK’ (single guidance package) types of software factories available from Microsoft and other vendors. It is becoming increasingly more common to combine and integrate the templates and recipes of these factories with one or more domain specific languages; each defined in their own DSL packages. Some factories desire a richer integration and user experience, and achieve this by adding additional Visual Studio eXtensibility (VSX) components, such as: services, tool-windows, editors, commands, menus etc. For these types of factories, the authors extend and enhance the capabilities of the software factory by creating a VSX project type package.

In the following sections, we explain what these relevant package project types are, how they work, and what the relevant MSI components are that you need to configure to build an installer package.

As far as what setup project technology or tool to use to create your installer, we leave the technical details of that to the final chapter ‘Creating a Combined Software Factory Installer’, where we put all this knowledge together and describe what you need to do to create a combined software factory installer that includes one or more of each of these package project types.

VSX Packages

Note. A VSX package was formerly referred to as a Visual Studio Integration (VSIP) Package.

A common means to extend Visual Studio today is by creating a Visual Studio Extensibility (VSX) package project, to contain the various extensibility components and customizations you desire (i.e. the services, tool-windows, editors, commands, menus etc.).

Click here for larger image

Visual Studio ‘Add-ins’ are also another means of providing Visual Studio integration, but typically the level of integration required by software factories demands the implementation of VSX packages. VS Add-ins are not considered in this article.

Once developed, VSX packages are compiled and registered with Visual Studio before being loaded and used by Visual Studio at runtime. Registration is achieved by adding various registry entries to the Visual Studio registry hive representing each extensibility component. In managed .NET development of these packages, various attributes of the Managed Package Framework (MPF) are used to declare registration information for the various components in the VSX package. At compile time this registration information is collected and added to the registry using the package registration tool ‘regpkg.exe‘. This tool reflects over the MPF attributes of the compiled assembly and updates the registration information in the registry for Visual Studio. This enabled debugging of the package at development time.

You can obtain these registry settings at design time by exporting them from your package using regpkg.exe to a Registry file (‘*.reg’) or to a WIX file (‘*.wxi’), using the appropriate command line switches.

These registry settings along with your VSX package assembly are then included in your setup project and to build an installer to deploy your VSX package.

The creation and development of many extensibility components can be significantly accelerated by using the ‘VSSDK Assist’ toolkit, which encapsulates many of the best practices for developing Visual Studio extensibility components into a set of guidance automation recipes you can execute on your VSX package project. ‘VSSDK Assist’ is a community supported development tool.

At development time, to perform this registration automatically for the developer to enable debugging, a VSX package project file (‘*.csproj’) contains some VSX specific MSBUILD targets that invokes regpkg.exe. This ensures that any changes to package are updated in the registry for debugging.



<Project>
  <PropertyGroup>
    <TargetRegistryRoot>Software\Microsoft\VisualStudio\8.0Exp</TargetRegistryRoot>
    <RegisterOutputPackage>true</RegisterOutputPackage>
    <RegisterWithCodebase>true</RegisterWithCodebase>
  </PropertyGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <Import Project="$(ProgramFiles)\Visual Studio 2005 SDK\2007.02\VisualStudioIntegration\ _		Tools\Build\Microsoft.VsSDK.targets" />
...
</Project>


By default, for debugging, VSX packages are intended to be deployed privately and not to the Global Assembly Cache (GAC). (<RegisterWithCodebase>true</RegisterWithCodebase>)

However, for deployment of VSX packages, the best practice is to deploy and execute them from the GAC.

Creating an Installer

At present in Visual Studio there are no project types that create setup projects specifically for deployment of VSX packages. Setup projects must be manually created and configured by the VSX package developer. This process can be tedious and error prone because of its manual nature.

An example of a standard VS setup project and a WIX setup project for a VSX package can be found in the sample with this article.

Creating a VSX Installer Manually

The following sections details the MSI specific components (such as: registry searches, launch conditions, files, registry and custom actions) that are most important for creating an MSI compliant installer for this package project type.

The following section details what the relevant MSI components are, but does not detail how to implement them in any type of setup project technology. That information is deferred to the last section of the document where the details for implementing an installer, for both a standard setup project and a WIX setup project, are given in the context of creating a combined installer.

The following steps detail the process and MSI components for building a VSX installer.

1.     Ensure your VSX package project compiles.

2.     Add a setup project to your package solution.

3.     In the ‘bin\Debug’ directory of your VSX package project, execute the following command line:



"C:\Program Files\Visual Studio 2005
SDK\2007.02\VisualStudioIntegration\Tools\Bin\regpkg.exe" /regfile:"vsxpackage.reg"
"MyVsPackage.dll"

"C:\Program Files\Visual Studio 2005
SDK\2007.02\VisualStudioIntegration\Tools\Bin\regpkg.exe" /wixfile:"vsxpackage.wxi"
"MyVsPackage.dll"


Note. This script can be enhanced and used in a ‘Post Build’ event on the project.

Registry Searches

Name

Property Name

Registry Root

Registry Key

Value

Visual Studio Environment

VS2005ENV

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS

EnvironmentDirectory

Visual Studio Executable

VS2005EXE

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS

EnvironmentPath

Launch Conditions

Name

Condition Name

Install URL

Visual Studio 2005

VS2005ENV

http://msdn.microsoft.com/vstudio/

File System

File

Target

VSX Package Assembly

[TARGETDIR] or GAC

Registry

Import all registry entries from the ‘vsxpackage.reg’ file created earlier in step 3.

Ensure that any imported registry settings containing absolute file paths are replaced with relative paths prepended with [TARGETDIR] so they refer to absolute paths on target machine determined at install time.

Custom Actions

In the case of all VSX packages, after the package assembly has been installed, and after uninstall, Visual Studio needs to be instructed to reset its various resource caches; such as the toolbox, commands, templates etc. To do this, a custom action is required to execute the following command line:



devenv.exe /setup 


This command is only required to be executed once for all newly installed VSX packages.

Stage

Script

 

Install

[VS2005EXE] /setup

 

Uninstall

[VS2005EXE] /setup

 

Further Information

The process for completing a VSX installer is documented in detail on MSDN.

The Microsoft VSX team maintains the VSX Team Blog to provide information and the VSX MSDN Forum provides assistance for building and supporting Visual Studio extensibility packages.

GAT Packages

The Guidance Automation Toolkit (GAT) is the authoring tool for creating guidance packages (GP’s) which are loaded at runtime by the Guidance Automation eXtensions (GAX) runtime. Although GAX itself is a VSX package, the package projects which GAT creates are not VSX packages. These GAT projects are merely class library assemblies defining: custom references, actions, value providers and converters etc. These assemblies also contain project, file and solution templates and the recipes which are associated to the other classes in the assembly.

Click here for larger image

Registration and runtime integration with Visual Studio of the recipes, commands and templates of a custom GAT package is not done in the standard way normal VSX packages work. Instead, the Guidance Automation eXtensions (GAX) provides a runtime platform that loads guidance packages, and their recipes, commands and templates into Visual Studio as needed (i.e. when you open a solution associated to a GAT package).

All the design-time recipe information for a GAT package is contained with a single XML manifest file which defines various pieces of information about the package (including the package identity and name). This package manifest file is processed by various GAT and GAX components in order to register and load the package at runtime.

It is possible to split the recipes of this manifest into separate files which are included in the manifest using XInclude statements.

Unlike normal VSX Packages, the Visual Studio registration of GAT packages is performed by a separate tool. This tool is in fact a recipe that the authoring environment of GAT provides, which is associated to your guidance package solution. This recipe parses the package manifest file, and registers basic information about the GAT package: templates, commands and other information into the registry and file system. This information is then used for loading the guidance package at runtime by GAX.

To facilitate this registration process, and to allow setup projects to leverage this registration mechanism, a guidance package is created with an associated installer project containing an installer class to install that guidance package.

Click here for larger image

Notice that GAT utilizes a standard VS setup project to deploy the guidance package.

The association between the GAT package project and the installer class project is achieved by referencing the installer class project from the GAT package project (Usually a project reference within same solution).

When you register the GAT package (using the registration recipe) the installer class is invoked and registration tasks are performed on the GAT package project.

Creating an Installer

For creating an MSI installer for your guidance package, GAT automatically creates a standard VS setup project along with the installer class project and your guidance package project. This setup project includes the package assembly, and all the content files of the GAT package project (including the package manifest file and the various code templates etc.) and is configured automatically for the GAT package.

A ‘Custom Action’ is included in the setup project which invokes the installer class (contained in installer class project), passing the path of the package XML manifest file to the installer class. When the setup project is executed on the target machine, this custom action invokes the installer class to do the package registration on the installed content files.

Fortunately this setup project and installer mechanism are provided to you automatically when you create a custom guidance package solution, and no further configuration is required by the GAT package developer. However, one caveat with this mechanism is that you require a single dedicated installer class (one per assembly) for each GAT package assembly, and the assembly containing that installer class must be deployed to the ‘Public Assemblies’ folder of Visual Studio (by default: ‘C:\Program Files\Visual Studio 8\Common7\IDE\PublicAssemblies’), for both installation and un-installation of the GAT package. This is a requirement of where GAX is deployed by default.

It is entirely feasible to replace the provided standard setup project with a similar WIX setup project of your own, although you will have to manually create and configure the WIX setup project.

An example of a WIX setup project for a GAT package can be found in the sample with this article.

Creating a GAT Installer Manually

The following sections details the MSI specific components (such as: registry searches, launch conditions, files, registry and custom actions) that are most important for creating an MSI compliant installer for this package project type.

The following section details what the relevant MSI components are, but does not detail how to implement them in any type of setup project technology. That information is deferred to the last section of the document where the details for implementing an installer, for both a standard setup project and a WIX setup project, are given in the context of creating a combined installer.

The following steps detail the process and MSI components for building a GAT installer.

1.      Ensure your GAT package project compiles.

2.      Register your GAT package using the ‘Register Guidance Package’ recipe provided by GAX.

Registry Searches

Name

Property Name

Registry Root

Registry Key

Value

Visual Studio Environment

VS2005ENV

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS

EnvironmentDirectory

GAX Runtime

GAXRUNTIME

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\InstalledProducts\RecipeManagerPackage

Package

C# Language

CSHARP

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\InstalledProducts\Microsoft Visual C#

DefaultProductAttribute

Launch Conditions

Name

Condition Name

Install URL

Visual Studio 2005

VS2005ENV

http://msdn.microsoft.com/vstudio/

Guidance Automation Extensions

GAXRUNTIME

http://www.microsoft.com/resources/practices/application/services.mspx

C# Language

CSHARP

http://msdn.microsoft.com/vcsharp/productinfo/

File System

Folder Name

Property

Location

Always Create

Public Assemblies

PUBLICASSEMBLIES

[VS2005ENV]PublicAssemblies

True

 

File

Target

GAT Package Assembly

[TARGETDIR]

All GAT Package ‘Content’ Files

[TARGETDIR]

GAT Installer Assembly

[PUBLICASSEMBLIES]

Registry

No components.

Custom Actions

The custom actions required by GAT only exist in the form of installer classes that are included in the GAT installer project.

Stage

Installer Class

Custom Action Data

 

Install

True

/Configuration=”[TARGETDIR]MyGuidancePackage.xml”

 

Commit

True

/Configuration=”[TARGETDIR]MyGuidancePackage.xml”

 

Rollback

True

/Configuration=”[TARGETDIR]MyGuidancePackage.xml”

 

Uninstall

True

/Configuration=”[TARGETDIR]MyGuidancePackage.xml”

 

Where: ‘MyGuidancePackage.xml’ is the filename of your GAT manifest file in the GAT package project.

GAT Setup Projects

By default GAT creates and uses a standard VS setup project for deployment. This has a number of disadvantages when it comes to automating the build of the GAT solution related to the fact that a standard VS setup project cannot be built on a build server such as Team Foundation Server. This is because the standard VS setup project is not MSBUILD compliant.

WIX offers an alternative means to create a GAT setup project reusing the assets already provided by default from GAT such as the installer class, and WIX setup projects can be automated in a build process.

An example of a WIX setup project for a GAT package can be found in the sample with this article.

Further Information

The GAT registration and setup process is not currently documented in detail on MSDN. However the GAT MSDN Forum provides assistance in building and supporting custom GAT packages.

DSL Packages

The Domain-Specific Language Tools (DSL Tools) defines its extensibility components (i.e. designers, menu commands, tool-windows, etc.) in an enhanced VSX package project (the ‘DslPackage’ project in a DSL solution). This VSX package behaves and is registered and loaded in the same way as normal VSX packages.

Click here for larger image

All the Visual Studio extensibility components defined by a DSL definition are generated by text templates as source files in the package project. These components also utilize MPF attributes in the same way as VSX package components. At compile time, the compiled package assembly is registered with Visual Studio automatically in the same way as VSX packages using special MSBUILD commands in the project file (*.csproj). In addition, the DSL Tools adds the assembly to the GAC (gacutil.exe) each time the assembly is rebuilt.



<Project>
  <PropertyGroup>
    ...
    <TargetRegistryRoot>Software\Microsoft\VisualStudio\8.0Exp</TargetRegistryRoot>
    <RegisterOutputPackage>true</RegisterOutputPackage>
    <RegisterWithCodebase>false</RegisterWithCodebase>
    <GacTargetOutput>true</GacTargetOutput>
  </PropertyGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <Import Project="$(ProgramFiles)\Visual Studio 2005 SDK\2007.02\VisualStudioIntegration\ _		Tools\Build\Microsoft.VsSDK.targets" />
  <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\DSLTools\v2.0\ _		Microsoft.DSLTools.targets" />
...
</Project>


Notice that by default, for debugging, DSL packages are deployed to the GAC and not privately (<RegisterWithCodebase>false</RegisterWithCodebase>), unlike the default for VSX packages.

For deployment, like VSX packages, DSL package assemblies should also be deployed to the GAC.

Creating an Installer

For creating an installer for a DSL, the DSL Tools also provides a separate DSL setup project that you need to add this to your DSL solution manually.

Click here for larger image

The DSL Tools utilizes WIX (version 2.0) and a special setup project with text templates to generate the installer from the DSL definition and package project.

The DSL Tools don’t use WIX Votive 2.0 setup projects, instead the WIX files are contained within a standard class library project, and compiled using tools from the WIX 2.0 toolset and custom MSBUILD targets.

There are a number of reasons this is a WIX setup project instead of standard Visual Studio setup project. Primarily, as mentioned before, it is very hard to automate modifications to a standard setup project to synchronize with any changes to the DSL solution (i.e. resources, editors, menu commands, tool-windows, file extensions, etc.). In a standard setup project these would have to be manually configured and there would be no automation interface to automatically synchronize changes from DSL definition to setup project. Furthermore, is anticipated that DSL developers will customize a DSL project to some degree and potentially add other extensibility components, such as: menu commands, tool-windows, editors, etc. to their DSL package projects. These custom extensibility components will all need to be accounted for in the setup project for Visual Studio registration at install time. Again, this is very difficult to automatically synchronize with a standard setup project, so a WIX files are re-generated.

An example of a standard VS setup project for a DSL package can be found in the sample with this article.

Click here for larger image

To re-sync the setup project at any time, the DSL developer uses the ‘Transform Templates’ command in the DSL solution, and the WIX setup files in the DSL setup project are re-generated. This works because the text template directive processor referenced by the text templates (*.tt) navigates over the installer definition (InstallerDefinition.dslsetup), then locates the assemblies of the DSL and reflects over the MPF attributes of the DSL package assembly collecting the registration information.

The ‘InstallerDefinition.dslsetup’ file is generated the first time the setup project is added to the DSL solution, and contains information based upon the DSL definition when generated (e.g. the file extension and the language name). This information is not maintained or re-synced, and requires changes made in the DSL definition to be updated manually in this file.

The reflection of MPF attributes by the directive processors is done in a manner similar to that of regpkg.exe. The text templates re-generate the necessary WIX to reflect the latest changes in the current DSL solution.

It is important that the code for the DSL package is generated and built before the WIX files are re-generated, so that all MPF attributes are picked up in this process. Fortunately, the ‘Transform Templates’ command enumerates all text templates in order in the DSL solution. For a default DSL solution with default named projects (Dsl, DslPackage and Setup), the DSL package project is always re-generated before the WIX files in the setup project. However, this cannot be guaranteed if the DSL package and definition projects are renamed or the solution structure is altered. In those cases, you may require 2 transform passes to ensure correct synchronicity between setup project and DslPackage project.

Creating a DSL Installer Manually

The following sections details the MSI specific components (such as: registry searches, launch conditions, files, registry and custom actions) that are most important for creating an MSI compliant installer for this package project type.

The following section details what the relevant MSI components are, but does not detail how to implement them in any type of setup project technology. That information is deferred to the last section of the document where the details for implementing an installer, for both a standard setup project and a WIX setup project, are given in the context of creating a combined installer.

The following steps detail the process and MSI components for building a DSL installer.

1.      Add setup project to solution (if not already present).

2.      Transform Templates and ensure your DSL package project compiles.

3.      Rebuild the DSL solution

4.      In the ‘bin\Debug’ directory of your DSL package project, execute the following command line:



"C:\Program Files\Visual Studio 2005
SDK\2007.02\VisualStudioIntegration\Tools\Bin\regpkg.exe" /regfile:"dslpackage.reg"
"Company.MyLanguage.DslPackage.dll"

"C:\Program Files\Visual Studio 2005
SDK\2007.02\VisualStudioIntegration\Tools\Bin\regpkg.exe" /wixfile:"dslpackage.wxi"
"Company.MyLanguage.DslPackage.dll"


Note. This script can be enhanced and used in a ‘Post Build’ event on the project.

Registry Searches

Name

Property Name

Registry Root

Registry Key

Value

Visual Studio Environment

VS2005ENV

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS

EnvironmentDirectory

Visual Studio Executable

VS2005EXE

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS

EnvironmentPath

Visual Studio Root

VS2005DIR

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS

ProductDir

DSL Tools Redistrib

DSLTOOLS

HKLM

SOFTWARE\Microsoft\VisualStudio\DSLTools\2.0

RedistInstall

C# Language

CSHARP

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\InstalledProducts\Microsoft Visual C#

DefaultProductAttribute

VB Language

VISUALBASIC

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\InstalledProducts\Microsoft Visual Basic

DefaultProductAttribute

Launch Conditions

Name

Condition Name

Install URL

Visual Studio 2005

VS2005ENV

http://msdn.microsoft.com/vstudio/

DSL Tools Redistrib

DSLTOOLS

http://www.microsoft.com/vstudio/dsltools

C# Language

CSHARP

http://msdn.microsoft.com/vcsharp

VB Language

VISUALBASIC

http://msdn.microsoft.com/vb

Only include launch conditions for Visual Basic and C# if your DSL package requires those languages for any resources; such as: whether the DSL generated source code files.

File System

Folder Name

Property

Location

Always Create

Schemas

SCHEMAS

[VS2005DIR]Xml\Schemas

True

C# Templates

CSHARPTEMPLATES

[VS2005ENV] ItemTemplates\CSharp\1033

True

VB Templates

VBTEMPLATES

[VS2005ENV] ItemTemplates\VisualBasic\1033

True

 

File

Target

DSL Package Assembly

GAC

DSL Package Assembly

[TARGETDIR]

DSL Definition Assembly

GAC

DSL Definition Assembly

[TARGETDIR]

DSL Package Schema

bin\Debug\GeneratedCode\MyLanguageSchema.xsd

[SCHEMAS]

DSL Package C# Template

bin\Debug\CSharp\1033\MyLanguage.zip

[CSHARPTEMPLATES]

DSL Package VB Template

bin\Debug\VisualBasic\1033\MyLanguage.zip

[VBTEMPLATES]

Including the above template files for Visual Basic and C# depend on whether your DSL package generates those templates.

Registry

Import all registry entries from the ‘dslpackage.reg’ file created in pre-steps.

Ensure that any imported registry settings containing absolute file paths are replaced with relative paths pre-pended with [TARGETDIR] so they refer to absolute paths on target machine determined at install time.

Key

Sub Key

String Entry

Value

HKEY_CLASSES_ROOT

 

 

 

 

.xxx

(default)

xxx.1.0.0

 

xxx.1.0.0

(default)

Description of your file type

 

 

AlwaysShowExt

1

 

xxx.1.0.0\DefaultIcon

(default)

[TARGETDIR]Company.MyLanguage.DslPackage.dll,0

 

xxx.1.0.0\Shell\Open\Command

(default)

/“[VS2005ENV]devenv.exe/” /dde /“%1/”

 

xxx.1.0.0\Shell\Open\ddeexec

(default)

Open(/“%1/”)

 

xxx.1.0.0\Shell\Open\ddeexec\Application

(default)

VisualStudio.8.0

 

xxx.1.0.0\Shell\Open\ddeexec\Topic

(default)

system

Where, ‘xxx’ is the file extension of your DSL definition.

For example:



Windows Registry Editor Version 5.00
 
[HKEY_CLASSES_ROOT\.xxx]
@="xxx.1.0.0"
 
[HKEY_CLASSES_ROOT\xxx.1.0.0]
@="My Language"
[HKEY_CLASSES_ROOT\xxx.1.0.0]
"AlwaysShowExt"="1"
[HKEY_CLASSES_ROOT\xxx.1.0.0\DefaultIcon]
@="[TARGETDIR]Company.MyLanguage.DslPackage.dll,0"
[HKEY_CLASSES_ROOT\xxx.1.0.0\shell\Open\Command]
@="\"[VS2005ENV]devenv.exe\" /dde
\"%1&\""
[HKEY_CLASSES_ROOT\xxx.1.0.0\shell\Open\ddeexec]
@="Open(\"%1\")"
[HKEY_CLASSES_ROOT\xxx.1.0.0\shell\Open\ddeexec\Application]
@="VisualStudio.8.0"
[HKEY_CLASSES_ROOT\xxx.1.0.0\shell\Open\ddeexec\Topic]
@="system"


Custom Actions

Stage

Script

 

Install

 [VS2005EXE] /setup

 

Uninstall

 [VS2005EXE] /setup

 

Setup Project Launcher

The DSL tools provide a setup launcher (setup.exe) that can bootstrap the installer and install pre-requisites (such as the DSL tools runtime environment (DSLToolsRedist.msi)) on the target machine. This runtime environment is required to be installed to the target machine for the compiled DSL to execute.

To provide this setup launcher for your DSL package, deploy the following bootstrapping files along with your created MSI:

·         Setup.exe – located by default at: ‘C:\Program Files\Visual Studio 2005 SDK\2007.02\VisualStudioIntegration\Redistributables\DSLTools’

·         DSLToolsRedist.msi – located by default at: ‘C:\Program Files\Visual Studio 2005 SDK\2007.02\VisualStudioIntegration\Redistributables\DSLTools’

·         Settings.ini – containing the following text:



[Bootstrap]
Msi=MyDslLanguage.msi
ProductName=MyDslLanguage


The DSL Tools setup project automatically copies these files with the compiled MSI to the output directory.

DSL Setup Projects

By default the DSL Tools create a WIX setup project for a DSL solution. This has a number of advantages over a standard VS setup project specifically to do with being able to automate changes in the DSL definition with the setup project so they always remain in sync.

Further Information

The process for completing a DSL installer is documented on MSDN.

The DSL MSDN Forum provides assistance for building and supporting DSL packages.

Combining Components into Single Package

In some software factory cases it may make sense to consolidate components from VSX, GAT and DSL packages into a VSX package project. You may want to do this for versioning or deployment simplicity or in cases of simple software factory, where you are simply enhancing GAT or DSL packages with VSX features (i.e. tool-windows, services, editors, etc.).

For more complex factories (multiple GAT packages, multiple VSX packages) particularly those involving multiple DSL’s, it makes sense to separate the DSL packages from the VSX and GAT packages, because combining multiple DSL packages together is not recommended nor supported.

DSL <- VSX

Combining components from a VSX package into a DSL package is supported, since these types of packages are both full VSX packages that use MPF attributes, and both VSX and DSL packages are designed to operate when deployed to the GAC.

It is not recommended to deploy DSL package assemblies privately outside the GAC. This scenario is not currently supported.

To merge VSX package components into a DSL package is simply a matter of copying your source files from the VSX package to the DSL package, and potentially renaming the DSL package to reflect the name of your factory.

You’ll need to manually consolidate various source files such as the MPF package class (public class VsPackage) itself, command sets and resources etc., since you can only have one of each of these per package assembly. Depending on the enhancements to make, you will either have to use partial classes to extend the generated classes of the DSL package project, or modify the text templates of the DSL package project to include your VSX package code.

The DSL package project can in fact be renamed or combined with other VSX packages as long as the physical paths on the hard disk remain relative to the DSL definition project. This is because relative paths in the text templates of the DSL package project point to the physical location of the DSL definition file (*.dsl) in the DSL definition project. The DSL package project also depends on some resources located in the DSL definition project, so these need to be resolved if change are made to the relative location of the DSL definition project on disk.

Since the paths to the DSL definition file is defined in the text template files, and not in the included in the core templates provided by the DSL Tools, it is perfectly feasible to change these paths to reflect the new project structure.

GAT <- VSX

A GAT package can be ‘promoted’ to a full VSX package, and registered and used in the same way as VSX package, as well operating as a regular GAT package. In this way, you can add VSX components to be used in the recipes of your GAT package.

The resultant GAT package is required to be deployed privately and not in the GAC, since it depends on GAX which is not deployed to the GAC.

In this case, source files from the VSX package project can simply be copied to GAT package project. No source file collisions are expected. But the following additional steps are required to the GAT package project:

1.     Add the following MSBUILD import directive to the project file to reference the Visual Studio SDK (see ‘Import Element’ for more details).



<Import Project="$(VSSDKPath)2007.02\VisualStudioIntegration\Tools\Build\Microsoft.VsSDK.targets" />


2.     Add the following elements to the first <PropertyGroup> in the project file



<RegisterOutputPackage>true</RegisterOutputPackage>
<RegisterWithCodebase>true</RegisterWithCodebase>


3.     Register the assembly for COM interoperability in the project properties. (see ‘How to: Register a Component for COM Interop’ for more details).

4.     Create a new resource file (VsPackage.resx) and add to the project.

5.     Create a new class (VsPackage.cs) and add to the project:



[PackageRegistration(UseManagedResourcesOnly = true)]
[DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\8.0")]
[ComVisible(true)]
public class VsPackage : Microsoft.VisualStudio.Shell.Package
{
      public VsPackage()
	{

	}
}


6.     Add the ‘ProvideLoadKey’ MPF attribute on this VsPackage class. (see ‘ProvideLoadKey Attribute’ for more details).



 [ProvideLoadKey("Standard", "1.0", "My Software Factory", "MyCompany", 104)]


Where ‘104’ is the name of a string resource in the resource file for the Package Load Key (PLK) of the package class. (see ‘How to: Obtain a PLK’, and ‘How to: Register a PLK’ for more details).

7.     Add a GUID attribute on the VsPackage class. This is required for COM registration.



 [Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")]


You can use the GUIDGen.exe utility from the Visual Studio Tools menu to create unique GUIDS to use here.

See ‘Loading VsPackages’ for more MPF attributes applicable to package loading.

VSX <- GAT

It is possible to merge a GAT package into a VSX package, and copy all GAT files to the VSX package project.

Ensure that all content files (i.e. templates, snippets, package manifest file, etc.) are copied to output if modified.

GAT <- DSL?

Combining a GAT package project with a DSL package project is similar in nature to combining a GAT package project and VSX package project. However, a DSL package project is currently required to be deployed to the GAC. Currently, GAT packages cannot execute from the GAC because they depend on GAX which is currently deployed to the ‘Public Assemblies’ folder of Visual Studio, and not the GAC. Therefore, this scenario is not supported.

Creating a Combined Software Factory Installer

In the previous sections of this chapter we have seen what MSI components we need to combine to create individual installers for each of the package types (VSX, GAT and DSL). We have also touched briefly upon how to combine various combinations of the package types together.

So far we have identified each of the steps required to be taken to manually create the installers for each package type, and identified their relative differences, and tools to support their creation. The following illustration shows which components are needed for each package type and their relative sizes.

Click here for larger image

However, when building a software factory today, you are likely to want to package multiple VSX, GAT and DSL packages into a single setup project, and build a single installer, for ease of deployment and versioning. Currently there is little out of the box functionality, tools or documentation to help do this, and knowing the right steps to create these setup projects is a source of pain for most software factory builders.

Click here for larger image

Merge Modules or Single Installer?

One of the first questions that come up when combining multiple package projects into a single installer is what approach to take considering each piece as a separate component (i.e. each DSL, GAT or VSX package).

Merge Modules (MSM) are intended to be used to package reusable deployment components to be included in other MSI’s (e.g. class libraries, frameworks etc.) The most common example of an MSM is the.NET Framework. At first sight, MSM’s may seem like the ideal means to package each package (VSX, GAT and DSL) to modularize the configuration and installation logic for each package. Then combine them together as a software factory with a ‘master’ MSI. However, this approach may not make sense when those packaged components are tightly related or dependent on each other, in the cases where those packages can’t be deployed independently. This is likely to be the case for types of software factory solutions being addressed in this article.

If you have packages which could be deployed independently (e.g. an independent DSL that you could share across many factories), creating a MSM for it and including that as part of a master MSI may make sense.

Although this document and its samples do focus upon the creation of a single MSI installer, MSM’s are not excluded and should be used where they make sense from a deployment reuse perspective. The information provided in this article for creating a single MSI will also apply to creating individual MSM’s.

Both standard VS setup projects and WIX setup projects are capable of creating MSM’s, and also creating master MSI’s to package the MSM’.

Creating a Setup Project

From the previous sections it should be apparent that we have one of two setup technologies to leverage for the combined installer we could create: either a standard VS setup project, or a WIX setup project. Either can provide a suitable solution, and in either case, the resulting MSI or MSM would be almost the same, albeit different in how they were assembled.

Note that if you intend to automate the build of your setup projects using an MSBUILD environment (such as Team Foundation Server), then using WIX is the only viable option, since standard VS setup projects use proprietary project file formats that are not MSBUILD compatible.

The next sections detail what the steps are required to manually build a single installer, to which you can include any number of VSX, GAT or DSL packages for your software factory. We will demonstrate how to implement these steps using both setup technologies: Standard VS setup project, and a WIX setup project.

Creating a Standard VS Setup Project

If implementing your installer using a standard VS setup project, simply add a new blank ‘Setup Project’ to your software factory solution.

Click here for larger image

Configuring the VS Setup Project

The setup project provides all the editors for: files, registry, launch conditions and custom actions accessible from the toolbar of ‘Solution Explorer’ when the setup project is selected.

Click here for larger image

The properties for the installer itself appear in the ‘Properties Grid’ when the setup project is selected.

Click here for larger image

You can also change the file name of the created installer for the selected build configuration by right-clicking on the project node in ‘Solution Explorer’ and selecting ‘Properties’.

You can find an example of a fully configured VS setup project in the sample code with this article.

More Information

Further details for configuring a standard VS setup project can be found online for creating and configuring standard VS setup projects.

Creating a WIX Setup Project

If implementing your installer using WIX, an alternative to using WIX Votive setup projects will be used to create a WIX project that is both MSBUILD compliant and that utilizes the WIX 2.0 toolset. This is because, as noted at the start of this document; WIX Votive 2.0 is not used because it defines a non-MSBUILD compliant project file. Votive 3.0 is, which is MSBUILD compliant, is also not used because it is currently not released and not stable, and it uses a different version of WIX (version 3.0) which is also different than and incompatible with the current version of WIX used by the DSL Tools.

In order to maintain consistency with the WIX implementation that the DSL Tools uses, and to avoid multiple versions of WIX on the same machine, we define a similar WIX implementation to that which is used by the DSL Tools. That is, to use standard class library project containing WIX 2.0 files, and then use the WIX MSBUILD targets to compile the WIX files into an MSI.

The WIX 2.0 toolset can be downloaded from wix.sourceforge.net. Note that in order to obtain the WIX specific MSBUILD targets you must obtain a toolkit version greater than 2.0.4.

At the time of writing the current version of WIX 2.0 is 2.0.5325.

Configuring the WIX Project

The DSL Tools ship specialized WIX MSBUILD targets which are specific to DSL’s, and dependent on the Visual Studio SDK. These targets have a number of enhancements over the targets shipped with WIX. For software factory solutions that include DSL’s it is recommended to use the MSBUILD targets provided by the DSL tools since these targets include tasks that package the MSI in ways that are more suitable for DSL packaging and deployment (i.e. the inclusion of a DSL tools redistributable boot-strapper). For software factory solutions that don’t include DSL’s, the MSBUILD targets installed by the WIX toolset are sufficient, and furthermore have no dependency on the Visual Studio SDK.

Following are the basic steps to configure a WIX setup project that is MSBUILD compliant using WIX 2.0. A number of these steps are different depending on if you intend to include a DSL in the installer.

You can find full examples of this setup project in the sample code with this article.

Creating the Setup Project

1.     Add a standard ‘Class Library’ project to your software factory solution (e.g. A C# class library)

2.     Delete all source files from the project, including the ‘AssemblyInfo.cs’ file in the ‘Properties’ folder.

3.     Remove all assembly references

4.     Add a ‘Resources’ folder to the project, and add the following files:

a.     ‘Product.ico’ icon file to represent the product in Add/Remove programs.

b.     ‘ReadmeShortcut.ico’ icon file to represent a shortcut to the readme file in Start menu.

c.      ‘BannerBitmap.bmp’ a 500x70 pixel bitmap image (256 colors) to be used as the dialog banner.

d.     ‘UpFldrBtn.bmp’ a bitmap for the ‘navigate to parent folder’ button in the select folder dialog.

e.     ‘NewFldrBtn.bmp’ a bitmap for the ‘new folder’ button in the select folder dialog.

5.     Add a ‘Files’ folder to the project, and add the following files:

a.     ‘Readme.htm’ containing installation details.

b.     If you want to package your Readme.htm file alongside the built MSI file as well as within the MSI, then set it’s ‘Copy to Output’ property to ‘Copy if newer’.

c.      ‘EULA.rtf’ an end-user license agreement to display on install.

6.     Add the following files to the project:

Full listings for these files can be found in the sample with this article.

·         Main.wxs – contains the Product, the Package, Properties, the Registry Searches, the Launch Conditions, and other WIX elements (Features, InstallUISequence, AdminUISequence, UI etc), with references to all other *.wxs files containing specific fragments. For example:



<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
    <Product UpgradeCode="A_UNIQUE_UPGRADE_GUID_HERE" Name="$(loc.ProductName)" Id="A_UNIQUE_GUID_HERE" Version="1.0.0" Manufacturer="$(loc.Manufacturer)" Language="1033" >
        <Package Id="A_UNIQUE_GUID_HERE" Manufacturer="$(loc.Manufacturer)" InstallerVersion="200" Platforms="Intel" Languages="1033" Compressed="yes" SummaryCodepage="1252" />
        <Property Id="FXINSTALLED">
            <RegistrySearch Id="FxInstalledRegistry" Key="SOFTWARE\Microsoft\NET Framework Setup\NDP\v2.0.50727" Name="Install" Root="HKLM" Type="raw"/>
        </Property>
        <Condition Message="$(loc.NetFrameworkRequired)">FXINSTALLED OR Installed</Condition>
        <Property Id="VS2005ENV">
            <RegistrySearch Id="VS2005EnvironmentRegistry" Root="HKLM" Key="Software\Microsoft\VisualStudio\8.0\Setup\VS" Name="EnvironmentDirectory" Type="directory" />
        </Property>
        <Condition Message="$(loc.VisualStudio2005Required)">VS2005ENV OR Installed</Condition>
        <Property Id="ALLUSERS">2</Property>
        <Property Id="ARPCONTACT"><![CDATA[$(loc.Manufacturer)]]></Property>
        <Property Id="ARPPRODUCTICON">Product.ico</Property>
        <Property Id="ARPURLINFOABOUT"><![CDATA[InsertProductUrlHere]]></Property>
        <Property Id="NEWERVERSIONMSG"><![CDATA[$(loc.ExistingVersionInstalled)]]></Property>
        <Property Id="ADMINORADVERTISEDMSG"><![CDATA[$(loc.AdminOrAdvertised)]]></Property>
 
        <Feature Id="DefaultFeature" Level="1" ConfigurableDirectory="TARGETDIR">
            <ComponentRef Id="CreateTargetDirectory"/>
            <ComponentRef Id="SupportingFiles"/>
            <ComponentRef Id="MyFactoryFiles"/>
        </Feature>
 
        <FragmentRef Id="RegistryFragment" />
 
        <Upgrade Id="A_UNIQUE_UPGRADE_GUID_HERE">
            <UpgradeVersion Minimum="0.0.0" Property="EXISTINGPRODUCTFOUND" OnlyDetect="yes" IncludeMinimum="yes" />
        </Upgrade>
        <Media Id="1" EmbedCab="yes" Cabinet="Cab1" />
        <Media Id="2" />
        <InstallUISequence>
            <LaunchConditions After="AppSearch" />
            <Custom Action="DIRCA_TARGETDIR" After="ValidateProductID">TARGETDIR=""</Custom>
            <Show Dialog="ResumeForm" After="IsolateComponents">Installed="" AND RESUME</Show>
            <Show Dialog="MaintenanceForm" After="ResumeForm"><![CDATA[Installed<>""]]></Show>
            <Show Dialog="WelcomeForm" After="CostFinalize">Installed="" AND NOT RESUME</Show>
            <Show Dialog="ProgressForm" After="WelcomeForm" />
            <Show Dialog="FatalErrorForm" OnExit="error">NOT HideFatalErrorForm</Show>
            <Show Dialog="UserExitForm" OnExit="cancel" />
            <Show Dialog="FinishedForm" OnExit="success" />
        </InstallUISequence>
        <AdminExecuteSequence>
            <Custom Action="ERRCA_ADMINORADVERTISED" Before="CostInitialize" />
        </AdminExecuteSequence>
        <AdvertiseExecuteSequence>
            <Custom Action="ERRCA_ADMINORADVERTISED" Before="CostInitialize" />
        </AdvertiseExecuteSequence>
        <InstallExecuteSequence>
            <RemoveExistingProducts After="InstallInitialize" />
            <LaunchConditions After="AppSearch" />            
            <Custom Action="DIRCA_TARGETDIR" After="ValidateProductID">TARGETDIR=""</Custom>
            <Custom Action="SET_DEVENV" After="DIRCA_TARGETDIR">DEVENV=""</Custom>
            <Custom Action="DEVENV_SETUP" After="InstallFinalize"/>
        </InstallExecuteSequence>
        <Binary Id="BannerBitmap" src="Resources\BannerBitmap.bmp" />
        <Binary Id="UpFldrBtn" src="Resources\UpFldrBtn.bmp" />
        <Binary Id="NewFldrBtn" src="Resources\NewFldrBtn.bmp" />
        <Icon Id="Product.ico" src="Resources\Product.ico" />
        <Icon Id="_ReadmeShortcut.ico" src="Resources\ReadmeShortcut.ico" />
    </Product>
</Wix>


·         Files.wxs – contains the directories and files. For example:



<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
    <Fragment>
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Component Id="CreateTargetDirectory" Guid="A_UNIQUE_GUID_HERE" DiskId="1" >
                <CreateFolder/>
            </Component>
            <Directory Id="ProgramMenuFolder" SourceName="USER'S" LongSource="User's Programs Menu">
                <Directory Id="ProgramMenuManufacturerDirectory" Name="Company" LongName="$(loc.Manufacturer)">
                    <Directory Id="ProgramMenuShortcutDirectory" Name="MyFactor" LongName="$(loc.ProductName)" />
                </Directory>
            </Directory>
            <Component Id="SupportingFiles" Guid="A_UNIQUE_GUID_HERE " DiskId="1">
                <File Id="_LicenseAgreement" Name="EULA.rtf" src="SourceDir\Files\EULA.rtf" Vital="yes" Compressed="yes" DiskId="1" />
                <File Id="_Readme" Name="Readme.htm" src="SourceDir\Files\Readme.htm" Vital="yes" Compressed="no" DiskId="2">
                    <Shortcut Id="_ReadmeShortcut" Directory="ProgramMenuShortcutDirectory" Name="Readme.htm" Icon="_ReadmeShortcut.ico" IconIndex="0" Show="normal" WorkingDirectory="TARGETDIR" />
                </File>
                <RemoveFolder Directory="ProgramMenuShortcutDirectory" On="uninstall" Id="ShortcutRemoveFolder" />
            </Component>
            <Component Id="MyFactoryFiles" Guid="A_UNIQUE_GUID_HERE" DiskId="1">
                <File Id="MyAssembly" KeyPath="yes" Name="MyAssemb.dll" LongName="Company.MyAssembly.dll" src="SourceDir\..\MyPackage\bin\Release\Company.MyAssembly.dll" Vital="yes" />
            </Component>
        </Directory>
    </Fragment>
</Wix>


·         Registry.wxs – contains registry entries. For example:



<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
    <Fragment Id="RegistryFragment">
        <FeatureRef Id="DefaultFeature">
            <ComponentRef Id="MyFactoryRegistry" />
        </FeatureRef>
 
        <DirectoryRef Id="TARGETDIR">
            <Component Id="MyFactoryRegistry" Guid="A_UNIQUE_GUID_HERE">
                <Registry Root="HKLM" Key="Software\$(loc.Manufacturer)\$(loc.ProductName)" Id="RegEntry1" Type="string" Value="MyValue" />
            </Component>
        </DirectoryRef>
    </Fragment>
</Wix>


·         CustomActions.wxs – contains custom actions. For example:



<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
    <Fragment>
        <CustomAction Id="DIRCA_TARGETDIR" Return="check" Execute="firstSequence" Property="TARGETDIR" Value="[ProgramFilesFolder]$(loc.Manufacturer)\$(loc.ProductName)" />
        <CustomAction Id="ERRCA_CANCELEXISTINGVERSION" Return="check" Error="[EXISTINGVERSIONMSG]" />
        <CustomAction Id="ERRCA_ADMINORADVERTISED" Return="check" Error="[ADMINORADVERTISEDMSG]" />
        <CustomAction Id="SET_DEVENV" Return="check" Execute="immediate" Property="DEVENV" Value="[VS2005EXE]" />
        <CustomAction Id="DEVENV_SETUP" Property="DEVENV" ExeCommand="/setup /log" Return="ignore" />
    </Fragment>
</Wix>


7.     UI.wxs – contains the UI.

Child elements of the <Dialog> elements are omitted for brevity



<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
    <Fragment>
        <UI>
            <Property Id="EulaForm_Property">No</Property>
            <Property Id="EulaForm_NextArgs">FolderForm</Property>
            <Property Id="EulaForm_PrevArgs">WelcomeForm</Property>
            <Property Id="WelcomeForm_NextArgs">EulaForm</Property>
            <Property Id="FolderForm_PrevArgs">EulaForm</Property>
            <Property Id="FolderForm_NextArgs">ConfirmInstallForm</Property>
            <Property Id="ConfirmInstallForm_PrevArgs">FolderForm</Property>
            <Property Id="SFF_UpFldrBtn">UpFldrBtn</Property>
            <Property Id="SFF_NewFldrBtn">NewFldrBtn</Property>
            <Property Id="MaintenanceForm_Action">Repair</Property>
            <Property Id="ErrorDialog">ErrorDialog</Property>
            <Property Id="DefaultUIFont">DefaultUIFont.1</Property>
            <TextStyle Id="DefaultUIFont.1" FaceName="MS Sans Serif" Size="9" Red="0" Green="0" Blue="0" />
            <TextStyle Id="VSI_MS_Sans_Serif13.0_0_0" FaceName="MS Sans Serif" Size="9" Red="0" Green="0" Blue="0" />
            <TextStyle Id="VSI_MS_Sans_Serif16.0_1_0" FaceName="MS Sans Serif" Size="12" Red="0" Green="0" Blue="0" Bold="yes" />
            <TextStyle Id="VSI_MS_Shell_Dlg13.0_0_0" FaceName="MS Shell Dlg" Size="9" Red="0" Green="0" Blue="0" />
            <Dialog Id="UserExitForm" Width="373" Height="287" Title="[ProductName]">...</Dialog>
            <Dialog Id="FatalErrorForm" Width="373" Height="287" Title="[ProductName]"> ...</Dialog>
            <Dialog Id="MaintenanceForm" Width="373" Height="287" Title="[ProductName]"> ...</Dialog>
            <Dialog Id="ResumeForm" Width="373" Height="287" Title="[ProductName]"> ...</Dialog>
            <Dialog Id="FinishedForm" Width="373" Height="287" Title="[ProductName]"> ...</Dialog>
            <Dialog Id="Cancel" Width="271" Height="78" Title="[ProductName]" NoMinimize="yes">...</Dialog>
            <Dialog Id="WelcomeForm" Width="373" Height="287" Title="[ProductName]"> ...</Dialog>
            <Dialog Id="FolderForm" Width="373" Height="287" Title="[ProductName]" TrackDiskSpace="yes">...</Dialog>
            <Dialog Id="SelectFolderDialog" Width="313" Height="223" Title="$(loc.BrowseForFolderTitle)" NoMinimize="yes">...</Dialog>
            <Dialog Id="ConfirmInstallForm" Width="373" Height="287" Title="[ProductName]"> ...</Dialog>
            <Dialog Id="EulaForm" Width="373" Height="287" Title="[ProductName]">...</Dialog>
            <Dialog Id="ProgressForm" Width="373" Height="287" Title="[ProductName]" Modeless="yes">...</Dialog>
            <Dialog Id="ErrorDialog" Width="330" Height="101" Title="[ProductName]" ErrorDialog="yes">...</Dialog>
            <Dialog Id="ConfirmRemoveDialog" Width="271" Height="78" Title="$(loc.ConfirmRemoveTitle)" NoMinimize="yes">...</Dialog>
            <Dialog Id="FilesInUse" Width="361" Height="177" Title="$(loc.FilesInUseTitle)" NoMinimize="yes">...</Dialog>
        </UI>
    </Fragment>
</Wix>


8.     Replace the attribute value ‘A_UNIQUE_GUID_HERE’ in all files with instances of unique GUID’s.

9.     Replace the two attribute values ‘A_UNIQUE_UPGRADE_GUID_HERE’ in ‘Main.wxs’ with the same unique GUID.

10. For each of the WIX files (*.wxs) in the project, set the ‘Build Action’ to ‘Compile’

11. Add the file ‘Strings.wxl’ to the project with the following content:

Some <String> elements are omitted for brevity



<WixLocalization
xmlns="http://schemas.microsoft.com/wix/2003/11/localization">
    <String Id="Manufacturer">Company</String>
    <String Id="ProductName">MyFactory</String>
    <String Id="FileDescription">MyFactory File</String>
    <String Id="VisualStudio2005Required">This setup requires Microsoft Visual Studio 2005.  Please install Microsoft Visual Studio 2005 and run this setup again.</String>
    <String Id="NetFrameworkRequired">This setup requires the Microsoft .NET Framework 2.0.  Please install the .NET Framework and run this setup again.</String>
    <String Id="AdminOrAdvertised">This installer package does not support Admin or Advertised installations.</String>
    <String Id="ExistingVersionInstalled">Unable to install because an existing version of this product is already installed.  You must uninstall this version before installing the product.</String>
    <String Id="FilesInUseTitle">[ProductName] Files in Use</String>
...
</WixLocalization>


12. Set the ‘Build Action’ of  ‘Strings.wxl’ to ‘None’

13. Unload the setup project, and edit the project file (*.csproj) in Visual Studio.

14. Make the following changes to the content of the project file:

a.     Add the following elements to the first <PropertyGroup> element (‘Debug’ configuration):



<OutputName>MyFactory</OutputName>
<LocalizedStringFile>Strings.wxl</LocalizedStringFile>
<SuppressAssemblies>True</SuppressAssemblies>
<VerboseOutput>True</VerboseOutput>


b.     In the <PropertyGroup> element (‘Debug|AnyCPU’ configuration), replace the value of the <DefineConstants> element, and set the <WarningLevel> value to ‘0’:



<DefineConstants>Configuration=Debug</DefineConstants>
<WarningLevel>0</WarningLevel>


c.     In the <PropertyGroup> element (‘Release|AnyCPU’ configuration), replace the value of the <DefineConstants> element, and set the <WarningLevel> value to ‘0’:



<DefineConstants>Configuration=Release</DefineConstants>
<WarningLevel>0</WarningLevel>


d.     Delete the <ItemGroup> element containing the ‘Properties’ folder:



  <ItemGroup>
    <Folder Include="Properties\" />
  </ItemGroup>


Completing a Non-DSL Setup Project

If not packaging one or more DSL package projects into your setup project you will need to complete these additional steps.

1.     Make the following changes to the content of the project file:

a.     Add the following elements to the first <PropertyGroup> element (‘Debug’ configuration):



<OutputType>package</OutputType>
<ToolPath>$(MSBuildExtensionsPath)\WIX\v2.0</ToolPath>
<BaseInputPath>$(MSBuildProjectDirectory)</BaseInputPath>


b.     Replace the <Import> element for ‘Microsoft.CSharp.targets’ with:



<Import Project="$(MSBuildExtensionsPath)\WIX\v2.0\wix.targets" />


c.     Save and reload the setup project.

When reloading the project again, you may receive this security warning. This is because Visual Studio has detected important changes to the project file, which have the potential to execute when opening the project. The customizations detailed here don’t represent a security threat in this respect, and you should ‘Load project normally’ (second option) if prompted.

Click here for larger image

2.     You will need to install the WIX toolset and its MSBUILD targets.

a.     Download the WIX toolset binaries  (binaries.zip)

b.     Create a the directory  ‘C:\Program Files\MSBuild\WIX\v2.0’

c.     Extract all files from the WIX download into this new directory.

Completing a DSL Inclusive Setup Project

The following additional steps are required if you are packaging one or more DSL package projects into your setup project. In this case it is best to leverage the specialized MSBUILD targets provided by the DSL Tools instead of using the MSBUILD targets provided by the WIX toolset.

1.     Add the file ‘settings.ini’ to the project with the following content:



[Bootstrap]
Msi=MyFactory.msi
ProductName=MyFactory


2.     Make the following changes to the content of the project file:

a.     Add the following elements to the first <PropertyGroup> element (‘Debug’ configuration):



<SetupIniFile>settings.ini</SetupIniFile>


b.     Replace the <Import> element for ‘Microsoft.CSharp.targets’ with:



<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\DSLTools\v2.0\wix.targets" />


c.     Replace the <None> element for the ‘settings.ini’ file, with a <SetupFiles> element:



<SetupFiles Include="settings.ini" />


d.     Save and reload the setup project.

Click here for larger image

Building the Setup Project

To compile the MSI installer, simply build the project in the solution. The MSI will be output to the project output folder (by default: ‘bin\Debug’, depending on the solution build configuration).

If you included one or more DSL’s in the setup project, and followed the specific instructions for that above, the boot-strapper (setup.exe) and DSL Tools redistributable (DSLToolsRedist.msi) will also appear in the output directory alongside the MSI.

More Information

Further details for completing the WIX files can be found for WIX authoring and the WIX schema.

Creating a Software Factory Installer Manually

The following sections details the MSI specific components (such as: registry searches, launch conditions, files, registry and custom actions) that are most important for creating an MSI compliant installer that includes all package project types.

The first part of each sub-section explains what the relevant components are (from previous sections), followed by the implementation steps for both a standard VS setup project and a WIX setup project.

1.     Ensure all your (VSX, GAT, DSL) package projects compile successfully

2.     Ensure each GAT package registers successfully

Registry Searches

1.     Create the following common registry searches:

Name

Property Name

Registry Root

Registry Key

Value

Visual Studio Environment

VS2005ENV

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS

EnvironmentDirectory

Visual Studio Executable

VS2005EXE

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS

EnvironmentPath

2.     If including any GAT packages, include the following registry searches:

Name

Property Name

Registry Root

Registry Key

Value

GAX Runtime

GAXRUNTIME

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\InstalledProducts\RecipeManagerPackage

Package

C# Language

CSHARP

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\InstalledProducts\Microsoft Visual C#

DefaultProductAttribute

3.     If including any DSL packages, include the following registry searches:

Name

Property Name

Registry Root

Registry Key

Value

Visual Studio Root

VS2005DIR

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS

ProductDir

DSL Tools Redistrib

DSLTOOLS

HKLM

SOFTWARE\Microsoft\VisualStudio\DSLTools\2.0

RedistInstall

C# Language

CSHARP

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\InstalledProducts\Microsoft Visual C#

DefaultProductAttribute

VB Language

VISUALBASIC

HKLM

SOFTWARE\Microsoft\VisualStudio\8.0\InstalledProducts\Microsoft Visual Basic

DefaultProductAttribute

Implementation

These are the comparable steps to create each ‘Registry Search’ in the various setup project technologies.

Standard VS Setup Project

 

1.     Select the setup project in ‘Solution Explorer’

 

2.     From the toolbar within ‘Solution Explorer’, open the ‘Launch Conditions’ editor

Click here for larger image

3.     Create a new ‘Registry Search’

Click here for larger image

4.     Define the registry search in the ‘Properties Window’

Click here for larger image

 

WIX Setup Project

1.     Open ‘Main.wxs’

2.     Add a <RegistrySearch> element within the <Product> element, after the <Package> element, for example:



  <Property Id="VS2005ENV">
      <RegistrySearch Id="VS2005EnvironmentRegistry" Key="SOFTWARE\Microsoft\ _	VisualStudio\8.0\Setup\VS" Name="EnvironmentDirectory" Root="HKLM" _	 Type="directory"/>
  </Property>


Launch Conditions

1.     Create the following common launch conditions:

Name

Condition Name

Install URL

Visual Studio 2005

VS2005ENV

http://msdn.microsoft.com/vstudio/

2.     If including any GAT packages, include the following launch conditions:

Name

Condition Name

Install URL

Guidance Automation Extensions

GAXRUNTIME

http://www.microsoft.com/resources/practices/application/services.mspx

C# Language

CSHARP

http://msdn.microsoft.com/vcsharp/productinfo/

3.     If including any DSL packages, include the following launch conditions:

Name

Condition Name

Install URL

DSL Tools Redistrib

DSLTOOLS

http://www.microsoft.com/vstudio/dsltools

C# Language

CSHARP

http://msdn.microsoft.com/vcsharp

VB Language

VISUALBASIC

http://msdn.microsoft.com/vb

Only include launch conditions for Visual Basic and C# if your DSL package requires those languages for any resources; such as: whether the DSL generated source code files.

Implementation

These are the comparable steps to create each ‘Launch Condition’ in the various setup project technologies.

Standard VS Setup Project

 

1.     Select the setup project in ‘Solution Explorer’

 

2.     From the toolbar within ‘Solution Explorer’, open the ‘Launch Conditions’ editor

Click here for larger image

3.     Create a new ‘Launch Condition’

Click here for larger image

4.     Define the condition in the ‘Properties Window’

Click here for larger image

 

WIX Setup Project

1.     Open ‘Main.wxs’

2.     Add  a <Condition> element following immediately after the <RegistrySearch> element that the launch condition applies to, for example:



  <Property Id="VS2005ENV">
      <RegistrySearch Id="VS2005EnvironmentRegistry" Key="SOFTWARE\Microsoft\ _	VisualStudio\8.0\Setup\VS" Name="EnvironmentDirectory" Root="HKLM" _	 Type="directory"/>
  </Property>
  <Condition Message="$(loc.VisualStudio2005Required)">VS2005ENV OR Installed _	</Condition>


Ensure that the localized string used in the message (i.e. VisualStudio2005Required) is defined in ‘Strings.wxl’ in the project.

File System

Directories

1.     If including any GAT packages, include the following directories:

Folder Name

Property

Location

Always Create

Public Assemblies

PUBLICASSEMBLIES

[VS2005ENV]PublicAssemblies

True

2.     If including any DSL packages, include the following directories:

Folder Name

Property

Location

Always Create

Schemas

SCHEMAS

[VS2005DIR]Xml\Schemas

True

C# Templates

CSHARPTEMPLATES

[VS2005ENV] ItemTemplates\CSharp\1033

True

VB Templates

VBTEMPLATES

[VS2005ENV] ItemTemplates\VisualBasic\1033

True

Files

1.     If including any VSX Packages, include the following files:

File

Target

VSX Package Assembly

[TARGETDIR], or GAC and [TARGETDIR]

2.     If including any GAT packages, include the following files:

File

Target

GAT Package Assembly

[TARGETDIR]

GAT Package Content Files

[TARGETDIR]

GAT Installer Assembly

[PUBLICASSEMBLIES]

3.     If including any DSL packages, include the following files:

File

Target

DSL Package Assembly

GAC and [TARGETDIR]

DSL Definition Assembly

GAC and [TARGETDIR]

DSL Package Schema

bin\Debug\GeneratedCode\MyLanguageSchema.xsd

[SCHEMAS]

DSL Package C# Template

bin\Debug\CSharp\1033\MyLanguage.zip

[CSHARPTEMPLATES]

DSL Package VB Template

bin\Debug\VisualBasic\1033\MyLanguage.zip

[VBTEMPLATES]

Including the above template files for Visual Basic and C# depend on whether your DSL package generates those templates.

Implementation

These are the comparable steps to add each ‘Directory’ and ‘File’ in the various setup project technologies.

Standard VS Setup Project

 

1.     Select the setup project in ‘Solution Explorer’

 

2.     From the toolbar within ‘Solution Explorer’, open the ‘File System Editor’

Click here for larger image

3.     For known system folders, add the ‘Special Folder’

4.     For other custom folders, add a ‘Custom Folder’

Click here for larger image

5.     Define the custom folder properties using the ‘Properties Window’

Click here for larger image

6.     For package assemblies, add the primary output of the project containing assembly.

7.     For files, add a file from the hard disk

Click here for larger image

8.     From the ‘Detected Dependencies’ folder of the setup project. Ensure you exclude all .NET framework, Visual Studio and other dependencies files that are not assemblies or files you are installing explicitly.

All runtime dependencies of the added assemblies should already exist in target machine at install time.

Click here for larger image

 

WIX Setup Project

1.     Open ‘Files.wxs’

2.     Add a <Directory> element and contained <Component> element, for example:



  <Directory Id="TARGETDIR" Name="SourceDir">
      <Component Id="CreateTargetDirectory" Guid="A_UNIQUE_GUID_HERE" DiskId="1" >
          <CreateFolder />
      </Component>
      ...
      <Directory Id="VS2005ENV">
          <Directory Id="PublicAssemblies" Name="PubAsm" LongName="PublicAssemblies">
              <Component Id="MyPackageFiles" Guid="A_UNIQUE_GUID_HERE" DiskId="1">
                  <File Id="MyAssembly" KeyPath="yes" Name="ASM1.dll" LongName= _		"Company.MyAssembly.dll" src="SourceDir\..\MyPackage\bin\Debug\ _		Company.MyAssembly.dll" Vital="yes" />
              </Component>
          </Directory>
      </Directory>
      ...
  </Directory>


Ensure that added <Component> elements are added as <ComponentRef> elements in the <Feature> element in ‘Main.wxs’ file.

Registry

1.     If including any VSX Packages, in the ‘bin\Debug’ directory of each VSX package project, execute the following command line, and import the registration information:



"C:\Program Files\Visual Studio 2005
SDK\2007.02\VisualStudioIntegration\Tools\Bin\regpkg.exe" /regfile:"vsxpackage.reg"
"MyVsPackage.dll"

"C:\Program Files\Visual Studio 2005
SDK\2007.02\VisualStudioIntegration\Tools\Bin\regpkg.exe" /wixfile:"vsxpackage.wxi"
"MyVsPackage.dll"


Note. This script can be enhanced and used in a ‘Post Build’ event on the project.

2.     If including any DSL Packages, in the ‘bin\Debug’ directory of each DSL package project, execute the following command line, and import the registration information:



"C:\Program Files\Visual Studio 2005
SDK\2007.02\VisualStudioIntegration\Tools\Bin\regpkg.exe" /regfile:"dslpackage.reg"
"Company.MyLanguage.DslPackage.dll"

"C:\Program Files\Visual Studio 2005
SDK\2007.02\VisualStudioIntegration\Tools\Bin\regpkg.exe" /wixfile:"dslpackage.wxi"
"Company.MyLanguage.DslPackage.dll"


Note. This script can be enhanced and used in a ‘Post Build’ event on the project.

3.     If including any DSL Packages, create a new registry file containing the following keys and values, and import the registration information.

Key

Sub Key

String Entry

Value

HKEY_CLASSES_ROOT

 

 

 

 

.xxx

(default)

xxx.1.0.0

 

xxx.1.0.0

(default)

Description of your file type

 

 

AlwaysShowExt

1

 

xxx.1.0.0\DefaultIcon

(default)

[TARGETDIR]Company.MyLanguage.DslPackage.dll,0

 

xxx.1.0.0\Shell\Open\Command

(default)

/“[VS2005ENV]devenv.exe/” /dde /“%1/”

 

xxx.1.0.0\Shell\Open\ddeexec

(default)

Open(/“%1/”)

 

xxx.1.0.0\Shell\Open\ddeexec\Application

(default)

VisualStudio.8.0

 

xxx.1.0.0\Shell\Open\ddeexec\Topic

(default)

system

Where, ‘xxx’ is the file extension of your DSL definition.

See section on ‘Creating a DSL Installer Manually’ for an example.

Implementation

These are the comparable steps to add ‘Registry’ keys and values in the various setup project technologies.

Standard VS Setup Project

 

1.     Select the setup project in ‘Solution Explorer’

 

2.     From the toolbar within ‘Solution Explorer’, open the ‘Registry Editor’

Click here for larger image

3.     Import previous created *.reg files from previous steps using regpkg.exe

Click here for larger image

4.     Ensure that any imported registry settings containing absolute file paths are replaced with relative paths pre-pended with [TARGETDIR] so they refer to absolute paths on target machine determined at install time. (Not local paths on the development machine!)

Click here for larger image

 

WIX Setup Project

1.     Open ‘Registry.wxs’

2.     From the *.wxi files created in the previous steps using regpkg.exe, cut and paste the <Registry> elements into a <Component> element, for example:



  <Component Id="MyFactoryRegistry" Guid="A_UNIQUE_GUID_HERE">
      <Registry Root="HKLM" Key="Software\Company\SomeKey" Id="RegEntry1"_	 Type="string" Value="MyValue" />
      ...
  </Component>


Custom Actions

1.     If including any GAT Packages, use the provided installer class (in the GAT Installer Assembly present in [PUBLICASSEMBLIES] folder), for each GAT package, with the following settings

Stage

Custom Action Data

 

Install

/Configuration=”[TARGETDIR]MyGuidancePackage.xml”

 

Commit

/Configuration=”[TARGETDIR]MyGuidancePackage.xml”

 

Rollback

/Configuration=”[TARGETDIR]MyGuidancePackage.xml”

 

Uninstall

/Configuration=”[TARGETDIR]MyGuidancePackage.xml”

 

Where: ‘MyGuidancePackage.xml’ is the filename of the GAT manifest file in each of the GAT package projects.

2.     If including any VSX or DSL Packages, define the following custom actions.

Stage

Script

 

Install

 [VS2005EXE] /setup

 

Uninstall

 [VS2005EXE] /setup

 

You must ensure the order of these custom actions, is as represented here.

Implementation

These are the comparable steps to add ‘Custom Actions’ to the various setup project technologies.

Standard VS Setup Project

 

1.     If including any VSX or DSL Packages, create the following Installer class:

a.      Create a new assembly in your solution called ‘InstallerClasses’.

b.      Create a new class called ‘VSXPackageInstaller’

c.      Derive the class from System.Configuration.Install.Installer (You need an assembly reference to System.Configuration.Install).

d.      Mark the class with the RunInstaller(true) attribute

e.      Override the Install() and Uninstall() methods to invoke Visual Studio to reset.

Optionally, include the check to ensure no instances of Visual Studio are running.



  [RunInstaller(true)]
  public class VsxPackageInstaller : System.Configuration.Install.Installer
  {
      public override void Install(System.Collections.IDictionary stateSaver)
      {
          base.Install(stateSaver);
          CheckDevenv ();
          SetupVs();
      }
      public override void Uninstall(System.Collections.IDictionary savedState)
      {
          base.Uninstall(savedState);
          CheckDevenv ();
          SetupVs();
      }
   
      private void SetupVs()
      {
          string processPath = this.Context.Parameters["Path"];
          if (string.IsNullOrEmpty(processPath) == true)
              return;
   
          Process process = new Process();
          process.StartInfo.UseShellExecute = false;
          process.StartInfo.RedirectStandardError = true;
          process.StartInfo.RedirectStandardOutput = true;
          process.StartInfo.Arguments = "/setup /log";
          process.StartInfo.FileName = processPath;
          if (true == process.Start())
              process.WaitForExit();
      }
      private void CheckDevenv()
      {
          if (Process.GetProcessesByName("devenv").Length != 0)
          {
              throw new InvalidOperationException("Close all instances of _		Visual Studio before running this setup.");
          }
      }
  }


This custom action now requires the installer to pass the full path to the ‘devenv.exe’ application by assigning the ‘Path’ parameter in the custom action data.

2.     Select the setup project in ‘Solution Explorer’

 

3.     From the toolbar within ‘Solution Explorer’, open the ‘Custom Actions Editor’

Click here for larger image

4.     Add a new Custom Action, by selecting the deployed project output assembly containing the installer class

Click here for larger image

5.     Define the ‘CustomActionData’ for each of the stages (Install, Commit, Rollback, Uninstall)

Click here for larger image

6.     Ensure the order of the custom actions for each stage.

Click here for larger image

 

WIX Setup Project

1.     Open ‘CustomActions.wxs’

2.     Add a <CustomAction> element, for example.

Using an Installer Class:



  <CustomAction Id="SET_DEVENV" BinaryKey="InstallUtil" DllEntry="ManagedInstall" _	 Execute="deferred" Impersonate="no"/>
  <CustomAction Id="DEVENV_SETUP" Property="Install" Value="/Path= _	&quot;[VS2005EXE]&quot; /installtype=notransaction /action=install _	/LogFile= &quot;[#InstallerAssembly] _	&quot; &quot;[#InstallerConfigFile]&quot;" />


Using Inline Scripting:



  <CustomAction Id="SET_DEVENV" Return="check" Execute="immediate" _	 Property="DEVENV" Value="[VS2005EXE]" />
  <CustomAction Id="DEVENV_SETUP" Property="DEVENV" ExeCommand="/setup /log" _	 Return="ignore" />


Ensure that any custom actions are added to the <InstallExecuteSequence> elements in the ‘Main.wxs’ file. For example:



  <InstallExecuteSequence>
      <Custom Action="InstallSetProp" After="StartServices"> _	$InstallerFiles&gt;2</Custom>
      <Custom Action="Install" After="InstallSetProp"> _	$InstallerFiles&gt;2</Custom>
      <CustomAction="UninstallSetProp" After="MsiUnpublishAssemblies"> _	$InstallerFiles=2</Custom>
      <Custom Action="Uninstall" After="UninstallSetProp"> _	$InstallerFiles=2</Custom>
      <Custom Action="CommitSetProp" After="Rollback"> _	$InstallerFiles&gt;2</Custom>
      <Custom Action="Commit" After="CommitSetProp"> _	$InstallerFiles&gt;2</Custom>
      <Custom Action="RollbackSetProp" After="Install"> _	$InstallerFiles&gt;2</Custom>
      <Custom Action="Rollback" After="RollbackSetProp"> _	$InstallerFiles&gt;2</Custom>
  </InstallExecuteSequence>


OR



  <InstallExecuteSequence>
      <Custom Action="SET_DEVENV" After="DIRCA_TARGETDIR">DEVENV=""</Custom>
      <Custom Action="DEVENV_SETUP" After="InstallFinalize"/>
  </InstallExecuteSequence>


Full samples of standard VS Setup projects and WIX setup projects for all packages types (VSX, GAT and DSL) can be found in the sample with this article.

Summary

One of the most challenging parts of creating an installer for a software factory solution is knowing exactly what dependencies, components and configuration need to be installed to a target machine. For the types of package project types (VSX, GAT and DSL) involved in software factory solutions today, this information is neither obvious to derive nor trivial to implement.

Many of the package project types available today (GAT and DSL in particular) provide their own individual setup projects to create individual installers per instance of the package. None of these installer projects are focused on integrated solutions involving multiple packages, even of the same type. Practical software factory solutions today involve the integration of multiple package projects of various project types, and therefore packaging each individual package project yields poor deployment experience with multiple MSI’s for effectively the same software factory release. There are workarounds of course involving the ‘chaining’ of multiple MSI’s, but these are simply workarounds attempting to achieve a single installer end-user experience.

Armed with the knowledge contained in this article and the samples that come with it, a single software factory MSI installer can be created. However, creating that single, combined installer requires not only a knowledge of what to configure for each package type in the installer, but also which choice of setup project technology to move forward with during the software factory development.

WIX setup projects are becoming increasingly more popular as the means for building these installers because the XML files it relies upon are easy to generate with tools, such as text templates. Furthermore, using text templating technology, these tools have the ability to examine the metadata exposed by the packages in a software factory solution and synchronize changes made to the packages in the solution.

This article, and its samples, don’t provide the reader with any automation assets (such as templates or configuration languages) to automate the creation of WIX installer files. However, it does provide all the information required to create these templates and construct an installer configuration language that can be used to automate the configuration of an installer for a software factory solution composed of the package project types discussed in this article.

About the Authors

Jezz Santos is a Principal Product Development Consultant with Microsoft Consulting Services, who specializes in Enterprise Product Development, Guidance Automation and Software Factories. His IT career has led him around the globe in several countries of Europe, America, Asia and the South Pacific. He has been immersed in Microsoft product development since the mid 1990's in a multitude of development roles for various types of companies including research, ISV, GSI, and now as a field consultant. As the result of this work, he explores the means and methods of developing and packaging reusable assets and automated guidance, making it actionable and customizable in the form of Software Factories. Jezz currently works very closely as an advisor to the Microsoft patterns & practices team, the Visual Studio Architects (VSTESA) and the DSL Tools team to help realize the concrete vision of Software Factories for Microsoft. Jezz created one of the world’s first implementations of a software factory (the ‘EFx Factory’ which demonstrates many of the advanced features of a future generation of software factories to come from Microsoft. He now spends his time helping customers and partners realize the practical vision of software factories. His blog “Software and Factories, and making sense of it for you” is dedicated to socializing and advancing fellow software developers’ understanding of this space. He is very active in the software factory building community providing guidance and various tooling innovations pushing software factory development forward. Jezz is the owner and contributor to several open source CodePlex community projects for providing tooling extensions for Microsoft software factories. You can also find him speaking at various technical events, on building software factories.

Edward Bakker is an Architect working for LogicaCMG, a major international force in IT and business services. Edward has 12 years experience in developing software and now specializes in Service Orientation, Domain Specific Languages and Software Factories. He is involved in defining the Software Factories strategy for both LogicaCMG and its customers. He works with teams within Microsoft as an expert advisor to help realize the Software Factories vision and shares his experiences with the community to support the adoption of Software Factories on real life projects. Edward is currently a Visual Developer - Solutions Architect MVP and can be contacted via his blog “Guidance, Automation and Factories”

-----------------------------------------------------------------------------------------------------------------------------------------------------

The information contained in this document represents the current view of Microsoft Corporation on the issues discussed as of the date of publication.  Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information presented after the date of publication.

This White Paper is for informational purposes only.  MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS DOCUMENT.

Complying with all applicable copyright laws is the responsibility of the user.  Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation.

Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document.  Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

© 2007 Microsoft Corporation.  All rights reserved.

Microsoft, Visual Studio and other Microsoft products mentioned here are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.

The names of actual companies and products mentioned herein may be the trademarks of their respective owners.

-----------------------------------------------------------------------------------------------------------------------------------------------------

Show:
© 2014 Microsoft