Adding a database project reference (DBPro) to a WIX 3.0 project

I'm building some installers for the project currently working on, and because we use TFS and Team Build I wanted to have the ability of creating MSI packages from the build script run at the build server. 

Unfortunately MSBUILD doesn't natively support Visual Studio Setup projects so they won't compile your nice MSI setup packages out of the box. Of course you can just modify the MSBUILD script to add an EXEC task to run VS2005 in order to build the setup project, but that requires splitting the original solution (or creating a new one just for compiling the setup project) and this new setup project can't contain references to projects (all references must be changed into binary references).

For those reasons I explored WIX, the new (and open source) Windows Installer for Xml project from Microsoft, published in SourceForge and found in the Url

I started with WIX 3.0 because it fully supports MSBUILD, but the version I downloaded had some serious drawbacks (it lacked support for Votive project variables, for example) and that was a show stopper for me. I also tried the stable WIX 2.0 release, but the lack of MSBUILD support and some other bugs (like no support for dots in project names) was also a show stopper for me. After some time I download the latest (unstable) version of WIX 3.0 (build 3.0.3106.0) and everything worked like a charm. Integration with MSBUILD was beautiful, Votive project variables were supported again and even the dots in the project names works as expected!

I started to code the installer and I wanted to include some SQL scripts to create some databases on install, and I wanted to automate this as much as possible. I have some VS2005 DBpro database projects and wanted to include the output scripts from those projects into my WIX project. The first version just referenced the SQL files from the projects and compiled just fine in my desktop machine, but failed miserably when compiled on the build server because the output paths are very different (Team Build just copies all output from compiled projects in the DROP folder defined in the build script, and don't use the output folder defined in the source projects).

So, the solution was to include a project reference in the WIX project to the DbPro projects, and later use those project variables to include the output script files in the setup package. So far, so good....  except that Visual Studio won't let you add this kind of project reference!  If you try that you will get a nice dialog with an "Object Reference Not Set" error message. Not very helpful....

The solution is to add manually those references by editing the source WIX project file. You can do that by unloading the project in Visual Studio (right click on the project and select "Unload Project") and then right click again on the unloaded project and select the "Edit" option from the context menu. You can always use the good old notepad to do this, but the Visual Studio way is easier (and cooler...). After editing the source project file you can test everything by reloading the project (right click and click the "Reload Project" menu item).

Inside the WIX project file, near the end of the file (and inside the "ItemGroup" xml tag) you must add something like:

<ProjectReference Include="..\..\..\Databases\Workflow.Persistence\Persistence.dbproj">

Inside the <Project> xml tag you must type the project GUID you want to reference, and this project GUID can be found inside the project being references itself. In this case, I must open the "Persistence.dbproj" file and look for the "ProjectGuid" xml tag:

<Project DefaultTargets="Build" xmlns="">
    <Configuration Condition=" '$(Configuration)' == '' ">Default</Configuration>
    <DBProduct>SQL Server 2005</DBProduct>

After that, you should have those nice database project references in your WIX project, like this:

WIX DbPro References

Later, in the WIX setup script you can reference the output of those projects like this:

<Binary Id="CatalogDbScript" SourceFile="$(var.Catalog.TargetDir)\WFTCatalog.sql" />
Binary Id="PersistenceDbScript" SourceFile="$(var.Persistence.TargetDir)\WFTPersistence.sql" />
Binary Id="TrackingDbScript" SourceFile="$(var.Tracking.TargetDir)\WFTTracking.sql" />

As you can see, I'm adding a binary file to the setup package using the "TargetDir" variable for the referenced project. Isn't that nice?

Usign the cool WIX "SqlExtension" I can very easily include and run those database scripts when installing my project, but that's for another post.

Andrés G Vettori
EDS Top Gun - .NET Capability Architect

Leader of the C# Community of the Microsoft Users Group Argentina

No Comments