Windows Metro App for Kinect

Creating installer for the desktop application with the help of the wix, while doing desktop application deployment is also major role to play, you need a setup of your product, so you can either create a MSI of your product and ask end user to have the prerequisites install by himself or you choose to prepare a bundle of prerequisite application that you wanted to make sure present on the target PC to get start and run your application, like in my case .net framework, mssql compact and k-lite codec as a part of prerequisites for my product. So I decided to make an MSI for my product and create a bundle of prerequisites and my product MSI, so end user doesn’t have to install all the prerequisites individually. My single installer will check that on target machine and install one by one all prerequisites on target machine and then final my product.

Part 1: In this post I am covering the setup environment for creating the wix setup project, generate GUID, Link to Part 2.
Part 2 will cover generate MSI of the product by Wix variable defining, product details, organizing directory, components and shortcut for your projects, Link to Part 1 & Part 3.
Part 3 will cover the bundling, Link to Part 3 & Part 4.
Part 4 will cover providing custom UI to your setup and signing the bundle. Link to Part 3.

Creating installer for the desktop application with the help of the wix series Part 1 Prerequisites

How to create a wix setup project in visual studio?

Firstly you need to install the wix toolset find link in the prerequisites. Wix-intaller

Above will install the wix toolset on your machine and wix project template for your visual studio.

Wix-installer-process-code

In new project popup, select Windows Installer XML then select setup Project.

Wix-installer-process-code

Specify name to the project “DemoSetupProject” and then edit this Product.wxs file and give the manufacturer name in the product node of the XML file.

Then Add reference to the setup project. Wix-installer-process-code

Wix-installer-process-code

How to generate GUID?

There are many way to generate GUID, one of them is shown below with visual studio.

Creating installer for the desktop application with the help of the wix series Part 2

How to create MSI for your product by Wix?

Defining variable in the wix

 <?define nameOfVariable = value ?>

If you want to create installer targeting x64 or x86 machine it depends on your requirement, here i am creating installer for x64 bit machine.

 <?xml version="1.0" encoding="UTF-8"?>
 <?define ProcessorArchitecture = x64 ?>
 <?define Property_ProductVersion = "1.0.0.0" ?>
 <?define Property_Manufacturer = "Manufacture Name" ?>
 <?define Property_ProductName = "Product Name" ?>
 <!-- Set a specific product code based on the processor architecture build variable and you can also
 define your “if else” condition as follows--> 
 <?if $(var.ProcessorArchitecture)=x64 ?>
 <?define Property_ProductCode = "YourGUIDGoesHere" ?>
 <?else ?>
 <?define Property_ProductCode = "YourGUIDGoesHere" ?>
 <?endif ?>
 <?define Property_UpgradeCode = "YourGUIDGoesHere" ?>

Defining Wix for your product.

 <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
 <Product Id="*" 
 Name="$(var.Property_ProductName)" 
 Language="1033" Version="$(var.Property_ProductVersion)"  Manufacturer="$(var.Property_Manufacturer)" 
 UpgradeCode="$(var.Property_UpgradeCode)">

 <?if $(var.ProcessorArchitecture)=x64 ?>
 <Package Id="*" InstallerVersion="200" Compressed="yes" Platform="x64" 
 InstallScope="perMachine" InstallPrivileges="elevated" Description="$(var.Property_ProductName)"      Manufacturer="$(var.Property_Manufacturer)" />
 <?else ?>
 <Package Id="*" InstallerVersion="200" Compressed="yes" InstallScope="perMachine" AdminImage="yes"
 InstallPrivileges="elevated" Description="$(var.Property_ProductName)"
 Manufacturer="$(var.Property_Manufacturer)"/>
 <?endif ?>

The media table defines the location that the MSI will look to find source files during
installation or repair scenarios. In this case, the source files are in a cab file that will be embedded directly into the MSI at build time. EmbedCab=”yes” means that it will generate a single msi of your product.

 <MediaTemplate EmbedCab="yes" />

Define the directory structure for your product to get installed on which folder location on the target machine. This is a list of directories that are used by this product as installation locations or custom action file search locations.

  <Directory Id="TARGETDIR" Name="SourceDir">
  <!-- Define the directory structure for program files -->
  <!-- Install the application to the ProgramFiles64Folder for the 64-bit MSI.-->
  <?if $(var.ProcessorArchitecture)=x64 ?>
  <Directory Id="ProgramFiles64Folder" Name="Program Files">
  <Directory Id="APPLICATIONROOTDIRECTORYMANU" Name="$(var.Property_Manufacturer)">
  <Directory Id="APPLICATIONROOTDIRECTORY" Name="$(var.Property_ProductName)">
  <Directory Id="APPLICATIONROOTDIRECTORYIMAGES" Name="Images"/>
  </Directory>
  </Directory>
  </Directory>
  <?else ?>
  <!-- Install the application to the ProgramFilesFolder for the 32-bit MSI.-->
  <Directory Id="ProgramFilesFolder" Name="Program Files">
  <Directory Id="APPLICATIONROOTDIRECTORYMANU" Name="$(var.Property_Manufacturer)">
  <Directory Id="APPLICATIONROOTDIRECTORY" Name="$(var.Property_ProductName)">
  <Directory Id="APPLICATIONROOTDIRECTORYIMAGES" Name="Images"/>
  </Directory>
  </Directory>
  </Directory>
  <?endif ?>
  <!-- Define the directory structure program menu folder-->
  <Directory Id="ProgramMenuFolder">
  <Directory Id="ApplicationProgramsFolderManufacturer" Name="$(var.Property_Manufacturer)">
  <Directory Id="ApplicationProgramsFolder" Name="$(var.Property_ProductName)"/>
  </Directory>
  </Directory>
  <!-- Define the directory structure program menu folder-->
  <Directory Id="DesktopFolder" Name="Desktop"/>
  </Directory>

Once you have declared the directory structure for your product to be installed then its time to declare the component for those directories. For simplicity i am just taking one component for my product. “Source” is the path to the exe of the product in my case i have wpf project, so i am pointing it to the bin/release folder of the wpf project.

 <!-- Add files to your installer package -->
 <DirectoryRef Id="APPLICATIONROOTDIRECTORY">
 <!-- Add the 64-bit component to the 64-bit MSI-->
 <?if $(var.ProcessorArchitecture)=x64 ?>
 <Component Id="$(var.Property_ProductName).exe_$(var.ProcessorArchitecture)" Guid="YourGUIDGoesHere" Win64="yes">
 <File Id="$(var.Property_ProductName).exe_$(var.ProcessorArchitecture)" Source="..\bin\Release\$(var.Property_ProductName).exe" KeyPath="yes" Checksum="yes"  />
 </Component>
 <?else?>
 <!-- component to the 32-bit MSI. -->
 <Component Id="$(var.Property_ProductName).exe_$(var.ProcessorArchitecture)" Guid="YourGUIDGoesHere">
 <File Id="$(var.Property_ProductName).exe_$(var.ProcessorArchitecture)" Source="..\bin\Release\$(var.Property_ProductName).exe" KeyPath="yes" Checksum="yes"/>
 </Component>

Now its time to add component for the images folder that i create under the root of the application installed folder.

 <DirectoryRef Id="APPLICATIONROOTDIRECTORYIMAGES">
 <!-- Add the 64-bit component to the 64-bit MSI, and add the 32-bit registry -->
 <?if $(var.ProcessorArchitecture)=x64 ?>
 <Component Id="$(var.Property_ProductName)FolderImages_$(var.ProcessorArchitecture)" 
 Guid="YourGUIDGoesHere" Win64="yes">
    	 <File Id="SnapScreen1.png_$(var.ProcessorArchitecture)"  Source="..\Images\SnapScreen1.png"/>
 </Component>
   <?else?>
  	 <!-- component to the 32-bit MSI.-->
   <Component Id="$(var.Property_ProductName)FolderImages_$(var.ProcessorArchitecture)" 
   Guid="YourGUIDGoesHere">

Now its time to define the component for the shortcut of my product on desktop, start menu

 <Component Id="ApplicationShortcut_$(var.ProcessorArchitecture)" Guid="YourGUIDGoesHere" Win64="yes">
     <!--Create folders-->
    	 <CreateFolder Directory="ApplicationProgramsFolderManufacturer"/>
    	 <CreateFolder Directory="ApplicationProgramsFolder"/>
    	 <!--Remove folders-->
      <RemoveFolder Id="RemoveApplicationProgramsFolder" Directory="ApplicationProgramsFolder" 
      On="uninstall"/>
    	 <RemoveFolder Id="RemoveApplicationProgramsFolderManufacturer" 
         Directory="ApplicationProgramsFolderManufacturer" On="uninstall"/>
    	 <!--Create Shortcut at start menu item-->
    	 <Shortcut Id="ApplicationStartMenuShortcut_$(var.ProcessorArchitecture)"
         	Name="$(var.Property_ProductName)"
       	Description="$(var.Property_ProductName)"
        	Target="[APPLICATIONROOTDIRECTORY]$(var.Property_ProductName).exe"
          WorkingDirectory="APPLICATIONROOTDIRECTORY" Directory="ApplicationProgramsFolder"/>
     <!--Create registry for the Shortcut at start menu item-->
    	 <RegistryValue Root="HKCU" Key="Software\$(var.Property_Manufacturer)
       \$(var.Property_ProductName)" Name="StartMenuShortcut" Type="integer" Value="1" KeyPath="yes"/>
        <!--Create Shortcut at desktop-->
    	 <Shortcut Id="desktopShortcut_$(var.ProcessorArchitecture)" Directory="DesktopFolder"
               	Name="$(var.Property_ProductName)" Target="[APPLICATIONROOTDIRECTORY]
                $(var.Property_ProductName).exe" WorkingDirectory="APPLICATIONROOTDIRECTORY"/>
         <!--Create registry for the Shortcut at desktop-->
    	 <RegistryValue Id="regDesktopShortcut_$(var.ProcessorArchitecture)" Root="HKCU" 
          Key="Software\$(var.Property_Manufacturer)\$(var.Property_ProductName)"
          Name="DesktopShortcut" Type="integer" Value="1"/>
    	 <!-- Add the uninstall shortcut to your installer package -->
    	 <Shortcut Id="UninstallProduct_$(var.ProcessorArchitecture)"
              	Name="Uninstall $(var.Property_ProductName)"
              	Description="Uninstall $(var.Property_ProductName)"
              	Target="[System64Folder]msiexec.exe"
              	Arguments="/x [ProductCode]" Icon="UnInstallAppIcon.ico"/>
    	 <RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
    <RegistryValue Root="HKCU" Key="Software\$(var.Property_Manufacturer) \$(var.Property_ProductName)"
      Name="StartMenuUninstalledShortcut" Type="integer" Value="1"/>
 </Component>

Now we add icons for the app and map that icons to the property of the product. that will be displayed in exe and launching shortcut as desktop, menu item. “SourceFile” is the path to the icon file for your product that you wanted to use later for your product, desktop shotcut, add/remove program file.

  <Component Id="ApplicationShortcut_$(var.ProcessorArchitecture)" Guid="YourGUIDGoesHere" Win64="yes">
     <!--Create folders-->
    	 <CreateFolder Directory="ApplicationProgramsFolderManufacturer"/>
    	 <CreateFolder Directory="ApplicationProgramsFolder"/>
    	 <!--Remove folders-->
     <RemoveFolder Id="RemoveApplicationProgramsFolder" Directory="ApplicationProgramsFolder"
     On="uninstall"/>
    	 <RemoveFolder Id="RemoveApplicationProgramsFolderManufacturer"
       Directory="ApplicationProgramsFolderManufacturer" On="uninstall"/>
    	 <!--Create Shortcut at start menu item-->
    	 <Shortcut Id="ApplicationStartMenuShortcut_$(var.ProcessorArchitecture)"
         	Name="$(var.Property_ProductName)"
       	Description="$(var.Property_ProductName)"
        	Target="[APPLICATIONROOTDIRECTORY]$(var.Property_ProductName).exe"
              	WorkingDirectory="APPLICATIONROOTDIRECTORY" Directory="ApplicationProgramsFolder"/>
     <!--Create registry for the Shortcut at start menu item-->
    	 <RegistryValue Root="HKCU" Key="Software\$(var.Property_Manufacturer)\$(var.Property_ProductName)" 
         Name="StartMenuShortcut" Type="integer" Value="1" KeyPath="yes"/>
     <!--Create Shortcut at desktop-->
    	 <Shortcut Id="desktopShortcut_$(var.ProcessorArchitecture)" Directory="DesktopFolder"
               	Name="$(var.Property_ProductName)"
                Target="[APPLICATIONROOTDIRECTORY]$(var.Property_ProductName).exe"
                WorkingDirectory="APPLICATIONROOTDIRECTORY"/>
     <!--Create registry for the Shortcut at desktop-->
    	 <RegistryValue Id="regDesktopShortcut_$(var.ProcessorArchitecture)" Root="HKCU"
        Key="Software\$(var.Property_Manufacturer)\$(var.Property_ProductName)"
          Name="DesktopShortcut" Type="integer" Value="1"/>
    	 <!-- Add the uninstall shortcut to your installer package -->
    	 <Shortcut Id="UninstallProduct_$(var.ProcessorArchitecture)"
              	Name="Uninstall $(var.Property_ProductName)"
              	Description="Uninstall $(var.Property_ProductName)"
              	Target="[System64Folder]msiexec.exe"
              	Arguments="/x [ProductCode]" Icon="UnInstallAppIcon.ico"/>
    	 <RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
    	 <RegistryValue Root="HKCU" Key="Software\$(var.Property_Manufacturer)
       \$(var.Property_ProductName)"
         Name="StartMenuUninstalledShortcut" Type="integer" Value="1"/>
 </Component>

Leave a comment