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.
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.
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.).
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:
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.
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.
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.
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.
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.
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.
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.
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.
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.
The properties for the installer itself appear
in the ‘Properties Grid’ when the setup project is selected.
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.
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.
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 | .png) |
| 3.
Create a new ‘Registry Search’ | .png) |
| 4.
Define the registry search in the ‘Properties
Window’ | .png) |
| 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:
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 | .png) |
| 3.
Create a new ‘Launch Condition’ | .png) |
| 4.
Define the condition in the ‘Properties
Window’ | .png) |
| 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’ | .png)
|
| 3.
For known system folders, add the ‘Special
Folder’ 4.
For other custom folders, add a ‘Custom
Folder’ | .png)
|
| 5.
Define the custom folder properties using the ‘Properties
Window’ | .png)
|
| 6.
For package assemblies, add the primary output
of the project containing assembly. 7.
For files, add a file from the hard disk | .png)
|
| 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. | .png)
|
| | |
| 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’ | .png)
|
| 3.
Import previous created *.reg files from
previous steps using regpkg.exe | .png)
|
| 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!) | .png)
|
| 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’ | .png)
|
| 4.
Add a new Custom Action, by selecting the deployed
project output assembly containing the installer class | .png)
|
| 5.
Define the ‘CustomActionData’ for each of the
stages (Install, Commit, Rollback, Uninstall) | .jpg)
|
| 6.
Ensure the order of the custom actions for
each stage. | .png)
|
| | |
| 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= _ "[VS2005EXE]" /installtype=notransaction /action=install _ /LogFile= "[#InstallerAssembly] _ " "[#InstallerConfigFile]"" />
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>2</Custom>
<Custom Action="Install" After="InstallSetProp"> _ $InstallerFiles>2</Custom>
<CustomAction="UninstallSetProp" After="MsiUnpublishAssemblies"> _ $InstallerFiles=2</Custom>
<Custom Action="Uninstall" After="UninstallSetProp"> _ $InstallerFiles=2</Custom>
<Custom Action="CommitSetProp" After="Rollback"> _ $InstallerFiles>2</Custom>
<Custom Action="Commit" After="CommitSetProp"> _ $InstallerFiles>2</Custom>
<Custom Action="RollbackSetProp" After="Install"> _ $InstallerFiles>2</Custom>
<Custom Action="Rollback" After="RollbackSetProp"> _ $InstallerFiles>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.
-----------------------------------------------------------------------------------------------------------------------------------------------------