Installing a Windows Service

by Markus 2. November 2009 21:17

 

Installing a Windows Service

This is a real fun thing in WiX, because it is very simple and strait forward.

 

Step 1

Insert the Following Code: (In Product.wxs or in a Fragment)

<DirectoryRef Id="APPLICATIONROOTDIRECTORY">
….

<Component Id='PTTesterService' Guid='c219dabd-f46d-4bff-91a9-00d85a7eb3d3'
           SharedDllRefCount='no' KeyPath='no' NeverOverwrite='no' Permanent='no'
           Transitive='no' Win64='no' Location='either'>

  <File Id='TheTesterService.exe' Name='TheTesterService.exe' Source='..\bin\$(var.Configuration)\TheTesterService.exe'
        ReadOnly='no' KeyPath='yes' Vital='yes' Hidden='no' System='no'
        Checksum='no'  />

  <ServiceInstall Id='TheTesterServiceInstall' DisplayName='TheTesterService' Name='The Tester Service'
                  Description ='Description of TheTester Service...'
                  ErrorControl='normal' Start='auto' Type='ownProcess' Vital='yes'
                  Account='NT AUTHORITY\LocalService' />
  <ServiceControl Id='TheTesterServiceControl' Name='TheTesterService'
                  Start='install' Stop='uninstall' Remove='uninstall' />

</Component>

…..

</DirectoryRef>

 

Notes:

  • The Directory Ref is defining Where to install the Service Files.
  • Setting the Account to 'NT AUTHORITY\LocalService' is important for Windows 7 and probably later OS. Because Windows 7 is not allowing the Service to be installed with LocalSystem which would be the default

 

 

Step 2

Define in which Feature to install the Service:

 

<Feature Id="DefaultFeature" Title="PTTester" Level="1"  ConfigurableDirectory ="APPLICATIONROOTDIRECTORY">
   ….

  <!--Installing the Services-->
  <ComponentRef Id="PTTesterService"/>

   …….

</Feature>

 

<= Back to Content

Tags: ,

Installing Files

by Markus 29. October 2009 23:56

 

How to Install all the Files and Applications in your Product

This is the simple but fuzzy part.

Hint: In the provided sample Project there is a little C# Forms Application called GUIDGen (Source included). This is a comfortable little Tool to generate GUIDs.

 

Step 1

Define the Directories (Folders) to use.

 

<Directory Id="TARGETDIR" Name="SourceDir">
  <Directory Id="ProgramFilesFolder">
    <!--Folder for All Programm Files-->
    <Directory Id="COMPANYROOTDIRECTORY" Name="$(var.ManufacturerFolderName)">
      <Directory Id="APPLICATIONROOTDIRECTORY" Name="$(var.ProductName)">
        <Directory Id="APPLICATIONDATADIRECTORY" Name="DataSubDir" />
      </Directory>
    </Directory>

    <!--Folder for Menu Items-->
    <Directory Id="ProgramMenuFolder">
      <Directory Id="ProgramMenuCompanyFolder" Name="$(var.ManufacturerFolderName)">
        <Directory Id="ProgramMenuAppFolder" Name="$(var.ProductName)"/>
      </Directory>
    </Directory>

    <!--Folder for Desktop-->
    <Directory Id="DesktopFolder" Name="Desktop" />
  </Directory>
</Directory>

 

Note:

  • APPLICATIONDATADIRECTORY is optional and it is just for demonstration of creating a Sub Folder under the Application Folder.

 

Step 2

Define the Files and other things to be deployed. Insert the following code in the Product.wxs or in a Fragment File:

<DirectoryRef Id="APPLICATIONROOTDIRECTORY">
      <Component Id="TheTester_exe" Guid="{90EFC2EE-4AD3-F051-86A0-29C35B823F7B}">
        <File Id="TheTester.exe" Source="..\Bin\$(var.Configuration)\TheTester.exe" KeyPath="yes" Checksum="yes" />
      </Component>
      <Component Id="TheTesterSetupManagerDLL_dll" Guid="{182eaf28-053f-4e02-b187-ba3b3384fabe}">
        <File Id="TheTesterSetupManagerDLL.dll" Source="..\Bin\$(var.Configuration)\TheTesterSetupManagerDLL.dll" Vital="yes" KeyPath="yes" DiskId="1"/>
        <File Id="TheTesterSetupManagerDLL.dll.config" Source="..\Bin\$(var.Configuration)\TheTesterSetupManagerDLL.dll.config" Vital="yes" DiskId="1" />
      </Component>
      <Component Id="InstallUtilLib_DLL" Guid="{182eaf28-053f-4e02-b187-ba3b3384faba}">
        <File Id="InstallUtilLib.dll" Source="C:\windows\Microsoft.NET\Framework\v2.0.50727\InstallUtilLib.dll" KeyPath="yes"/>
      </Component>

       ……

    </DirectoryRef>

    <DirectoryRef Id="APPLICATIONDATADIRECTORY">
      <Component Id="TheTesterData_xml" Guid="{A1244677-9B25-4235-8622-9A0860B37B8F}">
        <File Id="TheTesterData.xml" Source="..\Bin\$(var.Configuration)\TheTesterData.xml" KeyPath="yes" Checksum="yes" />
      </Component>
    </DirectoryRef>

 

Step 3

Compose the Features Tag. Here we have only one Feature, but If you need more just separate the Files in more features. You need to use a different UI to select the Features to install than in this demo!!!!

 

<Feature Id="DefaultFeature" Title="PTTester" Level="1"  ConfigurableDirectory ="APPLICATIONROOTDIRECTORY">
  <!--Installing the Files-->
  <ComponentRef Id="TheTester_exe" />
  <ComponentRef Id="TheTesterSetupManagerDLL_dll" />
  <ComponentRef Id="InstallUtilLib_DLL" />

  <!--Installing DataFiles-->
  <ComponentRef Id="TheTesterData_xml" />

  <!--Installing the Services-->
  <ComponentRef Id="PTTesterService"/>

  <!--installing the Shortcuts-->
  <ComponentRef Id="ApplicationShortcut" />
  <ComponentRef Id="ApplicationShortcutDesktop" />

</Feature>

 

<= Back to Content

Tags: ,

Be prepared for Upgrades

by Markus 29. October 2009 23:30

 

Upgrades (New Versions of your Product) need to be installed

 

The Important message first:

Please test the Deployment of your Version 1.1 and 2.0 and if they Upgrade the Previous Versions correctly  > BEFORE  <  you deploy the Version 1.0!!!

 

Step 1

Have a look at and insert the following Tags in your Project.wxs

<?define ProductVersion="1.0.0" ?>
  <?define ProductName = "TheTester"?>
  <?define ProductTitle = "$(var.ProductName) $(var.ProductVersion)"?>
  <?define Manufacturer="The Tester GmbH &amp; Co. KG"?>
  <?define ManufacturerFolderName="The Tester GmbH"?>
  <?define ProductCode="{78BD1E9F-8DFD-443D-BD7A-0311BC0132EB}"?>
  <?define UpgradeCode="{BD56AC1E-2D89-4A36-9584-935A7AC06383}"?>

  <Product Id="$(var.ProductCode)"
           Name="$(var.ProductTitle)"
           Language="1031"
           Codepage ="1252"
           Version="$(var.ProductVersion)"
           Manufacturer="$(var.Manufacturer)"
           UpgradeCode="$(var.UpgradeCode)">

    <Package Id="*"
             Manufacturer="$(var.Manufacturer)"
             InstallerVersion="200"
             Compressed="yes"
             Languages="1031"/>

Notes:

  • In the first part there are some variables defined. The Variables can be used in other places. So if we need to change something we have only one place to change it…
  • Product.Id: This is the so called Product Code. This has to be changed for every Version of your Product
  • UpgradeCode: This has to stay the same for all versions of your product
  • Language: This has to stay the same for all versions of your product
  • Language defines NOT the UI language of your installer!!! the UI Language of your installer is defined in the properties page of the project under Build-Cultures to Build
  • Version needs to be in the Format ##.##.####
  • The Codepage in this example is for Germany
  • The Package.Id needs to be change for every build of the msi, so you can just keep the * there

 

Step 2

You have to insert the following Tags:

<Upgrade Id='$(var.UpgradeCode)'>
  <UpgradeVersion OnlyDetect='yes' Property='NEWERPRODUCTFOUND'
                  Minimum='$(var.ProductVersion)' IncludeMinimum='no' />
  <UpgradeVersion OnlyDetect='no'  Property='PREVIOUSVERSIONSINSTALLED'
                  Maximum='$(var.ProductVersion)' IncludeMaximum='no'/>
</Upgrade>

 

Notes:

  • Upgrade.Id has to be the same as UpgradeCode!!!!

 

Step 3

You have to define a custom actions

<CustomAction Id='NoDowngrade' Error=’A newer version is already installed.' />

 

Step 4

You have to schedule the custom action and the removal of the application.

<InstallExecuteSequence>
    <!--Check if newer Version is installed-->
    <LaunchConditions After='AppSearch'></LaunchConditions>
    <Custom Action='NoDowngrade' After='FindRelatedProducts'>NEWERPRODUCTFOUND</Custom>
    <!--Remove existing-->
    <RemoveExistingProducts After="InstallInitialize"/>
  </InstallExecuteSequence>

Notes:

  • The Check if a newer version is installed or not happens AFTER you are through all UI in your installer. I don’t like this behavior but I didn’t find another solution.
  • The RemoveExitingProduct is scheduled before the actual installation of the new version. If you want to schedule it after the installation of the ne version you can use After=”InstallFinalize”. Actually this is the recommended time slot.

 

<= Back to Content

Tags: ,

Prerequisites

by Markus 29. October 2009 23:08

 

How to tell WiX to install Prerequisites

 

Prerequisites like the DotNet Framework or SQL Server Express Edition and so on can not be defined in the wxs files. They have to be defined in the project File itself.

Step 1

  • Right click the Project in the Solution Explorer and click on Unload Project
  • Right click the Project in the Solution Explorer again and click on Edit <ProjectName>

Step 2

In the Project File right below the <Project …> Start Tag insert the Tags to define the Prerequisites you want enclosed in an Itemgroup Tag. E.g.:

 

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!--Add Bootstrapper Files here-->
  <ItemGroup>
    <BootstrapperFile Include="Microsoft.Net.Framework.3.5">
      <ProductName>.NET Framework 3.5</ProductName>
    </BootstrapperFile>
    <BootstrapperFile Include="Microsoft.Windows.Installer.3.1">
      <ProductName>Windows Installer 3.1</ProductName>
    </BootstrapperFile>
    <BootstrapperFile Include="Microsoft.SQL.Server.Compact.3.5">
      <ProductName>Microsoft SQL Server Compact 3.5</ProductName>
    </BootstrapperFile>
    <BootstrapperFile Include="Microsoft.SQL.Server.Compact.3.5 x64">
      <ProductName>Microsoft SQL Server Compact 3.5 x64</ProductName>
    </BootstrapperFile>
  </ItemGroup>

   ………

Notes:

  • For a normal Visual Studio 2008 installation some predefined Bootstrapper Packages are located under C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages
  • The String for the Include Attribute above can be found in the Product.xml file of the Package in the ProductCode Attribute of the Package Tag.
  • The Content of ProductName Tag above is, as far as I know, not important and you can just set a good name.

 

Step 3

At the End of the Project File place the following tag:

<Target Name="AfterBuild">
  <GenerateBootstrapper
    ApplicationFile="$(TargetFileName)"
    ApplicationName="My Application Name"
    BootstrapperItems="@(BootstrapperFile)"
    ComponentsLocation="Relative"
    CopyComponents="True"
    OutputPath="$(OutputPath)"
    Path="C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\" />
</Target>

This tells the WiX Compiler to create a Setup.exe Bootstrapper aside your .msi file.

 

Step 4

Save and close the Project File and right Click the Project in the Solution Explorer and Click on Reload Project

 

 

<= Back to Content

Tags: ,

Creating and organizing the Solution and important settings

by Markus 29. October 2009 21:20

 

Creating a Project

Open Visual Studio 2008 and create a new project – Select Wix – and WiXProject

ScreenShot026

 

Go to the Properties Page of the Project and verify the following Settings: (put in values that are good for you)

Installer

  • Output Name !!! Hint: Be aware that this name should stay the same over all versions of your product!!!

Build

  • Cultures to Build
  • Output Path

 

ScreenShot027

 

Adding References

You need to add the following references to the project

  • WixNetExtentions
  • WixUIExtentions
  • WixUtilExtentions
  • WixVSExtentions

 

Organizing the project

 

You can split the wxs files in so called fragments. Note, that there ist nothing like a using or include statement to join the files. The Wix Linker light is just getting all files together witch contains items references directly or inderectly from the Product.wxs.

We decided to put the major logic in the Product.wxs and have the UICustomizations an the definition of the Files in separate wxs files.

 

A simple Fragment is:

 

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
    <!--****************************************************************************************-->
    <!-- Define the Files and Services to be installed here –>
    <!--****************************************************************************************-->

    <DirectoryRef Id="APPLICATIONROOTDIRECTORY">
      <Component Id="PTTester.exe" Guid="{90EFC2EE-4AD3-F051-86A0-29C35B823F7B}">
        <File Id="PTTester.exe" Source="..\Bin\Debug\PTTester.exe" KeyPath="yes" Checksum="yes" />
      </Component>
    </DirectoryRef>

  </Fragment>
</Wix>

 

 

<= Back to Content

Tags: ,

Installing Wix

by Markus 29. October 2009 21:01

 

Installing Wix is very simple…

  • Download the latest Wix Toolkid from Sourceforge here and follow the instructions on the Wix Homepage
  • You should have some new project Templates in Visual Studios Create New Project Dialog like in the following picture

 ScreenShot026

 

<= Back to Content

Tags: ,

Wix Documentation – Start Page

by Markus 29. October 2009 20:10
Technorati-Tags: ,

(Created: November 2009)

A Quick Start Guide to Wix 3.0 / 3.5 for C# Developers

 

Usefull Links to Wix guides and documentations

 

Tags: ,

About MaHop.Net

Just look on our Webpage http://www.mahop.net

Tag cloud