Automating Web Deployment using Windows Installer XML (WIX)


Deployment of web sites is usually done by copying the compiled ASP.NET web site files into the target virtual directory using Copy Web Site or Publish web site features in Visual Studio and manually creating and configuring the Web Site in IIS.

Though this method is simple, it involves lot of manual effort in verifying the Pre Requisites, Creating/Modifying or Configuring the Web sites in IIS. We can automate this whole process by building a simple Windows Installer Package using WIX.

WIX installer package

  • Provides the features like Install, Un-Install, Repair and Remove to your Web Site similar to any other product install on your machine
  • You can check for all the Pre Requisites like OS Version, IIS version, and .NET Framework etc.. before proceeding with the deployment and inform the user about what happened with a nice UI
  • You can create a new web site, modify the existing web site,  Create Application Pools and configures IIS
  • During the un-install you can remove everything that is created (Web Site, Physical Directories) on Install and leave the target server in clean state
  • You can rollback the install changes in case of a failure

Create a Sample Web Site:

Let’s create a simple website and add a Web Deployment Project to it. We will build the installer package to deploy this web site on to the target server.

clip_image002

Fig 1: Sample web site and its Web Deployment project

 

Right click on Web Deployment project and open the Property pages to set up the output location for our compiled web site files. Leave the default values for this demo which is set to the project output folder. This location we will be the source for our installer package to pick up the required files while building the installer package.

clip_image004

Fig 2: Web Deployment Project property pages

Build the whole solution to see the output files in deployment project output location

clip_image006

Fig 3: Files in Web Deployment project output folder

 

Authoring Installer for our Sample Web Site:

Install the WIX 3.0 Visual Studio plug in from http://sourceforge.net/projects/wix/files/. And for basic understanding on the Directory, Component, Feature and other elements in WIX source files use the WIX documentation file in the installed location of the plug in or go to http://www.tramontana.co.hu/wix/.

Once the plug in is installed add the new WIX project to our sample web site solution by going to add new project –> Select WIX.

After you add it the solution looks like this

clip_image008

Fig 4: The web site and the set up project together in one solution

The Product.wxs is the WIX Source File which we will modify shortly to define our package components. Before that add references to WixIISExtension.dll and WixUtilExtension.dll in WIX binaries location to our WIX Project.

Now open the Product.wxs and add the following xml namespaces to get the intelliscenece for WIX IIS and other elements.

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
     xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension"
     xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">

The default directory structure defined in Product.wxs maps to “C:Program FilesApplicationName” which specifies the target install location for our package i.e. the location on target server which will have all the output files from our MyWebSite_deploy project (See Fig 3).

Under the INSTALLLOCATION directory add the following to define our first component

<!-- root level files –>
<Component Id="MySite_root_Files" Guid="E06FD7E9-8360-4e78-B10F-3F53E88FE1FB">
 <File Id="MySite_Default_aspx" Source="$(var.SolutionDir)MyWebSite_deploy$(var.Configuration) Default.aspx"/>
 <File Id="MySite_Web_Config" Source="$(var.SolutionDir)MyWebSite_deploy$(var.Configuration)Web.Config"/>
</Component>

 

The component MySite_root_Files defines all the files that are directly needs to be copied under the INSTALLLOCATION. The <File/> element specifies the actual file that needs to be copied and the source attribute specifies the complete source path of the file.

Source="$(var.SolutionDir)MyWebSite_deploy$(var.Configuration)Default.aspx"

$(var.SolutionDir) is a WIX pre-processor which gives the Solution folder path to the WIX compiler

$(var.Configuration) is another pre-processor which specifies the Active Configuration of the solution (i.e. Debug | Release)

Along with the files Default.aspx and Web.Config we also have bin folder in project output directory which needs to be created under the install location. So create the folder mapping INSTALLLOCATIONbin by adding the directory element under the INSTALLLOCATION directory. And define the component and file or Directory element for each of the files and directories under the bin folder as we have done for INSTALLLOCATION directory.

<!-- bin directory –>
 <Directory Id="MySite_bin_Directory" Name="bin">
   <Component Id="MySite_bin_Files" Guid="2ECC2543-856E-4ca7-8DB3-D1657245A41E">
     <File Id="MYSite_MySite_deploy_dll" Source="$(var.SolutionDir)MyWebSite_deploy$(var.Configuration)
             binMyWebSite_deploy.dll">
      </File>
    </Component>
  </Directory>

 

The same way we can add any number of directories and files mapping from source to the target location.

Setting up IIS web site:

So far we have seen how to move files from source to the target location by using the Directory, File and Component elements. But how can we configure IIS?

WIX has an API or an Extension (WIXIISExtension.dll) to interact with IIS. Remember that we have already added reference to this to our WIX Project. Add another component under the INSTALLLOCATION directory to define the configuration to create a web site in IIS.

<ComponentId="MyWebSite_IISConfigure" Guid="5146762F-0E78-47d2-A105-6E18E2993619" KeyPath="yes">
  <util:UserId="MyWebSite_AppPoolUser" Name="domainusername" Password="pwd"/>

  <!--define application pool-->
  <iis:WebAppPool Id="MyWebSite_AppPool" Name="MyWebSiteApplication"
                  Identity="other" User="MyWebSite_AppPoolUser"
                  RecycleMinutes="120" />

  <!--define web site-->
  <iis:WebSite Id="MyWebSite_Website" Description="MyWebSite"
               AutoStart="yes" StartOnInstall="yes" ConfigureIfExists="yes"
               Directory="INSTALLLOCATION" ConnectionTimeout="360" >

    <iis:WebAddress Id="MYSite_Bindings" IP="xx.xx.x.xxx" Port="80" Header="MyWebSite" />
    <iis:WebApplication Id="MY_WebApp" Name="MY Web Site" WebAppPool="MyWebSite_AppPool"
                        ScriptTimeout="360" />
    <iis:WebDirProperties Id="MyWebSite_Properties" AnonymousAccess="yes" WindowsAuthentication="no"
           DefaultDocuments="Default.aspx" />
  </iis:WebSite>
  </Component>

 

Most of the elements and their attributes in this component are self descriptive.

<Util:User/> define the domain user which can be referenced anywhere in the source file using the Id MyWebSite_AppPoolUser.

<iis:WebAppPool/> creates the application pool with the name MyWebSiteApplication. The attribute Identity = “Other” specifies that this application pool uses Custom account for identity. And the user attribute specifies the ID of the domainusername created anywhere in the source file using <Util:User/>

<iis:WebSite/> and its child elements <iis:WebAddress/>, <iis:WebApplication/> and <iis:WebDirProperties/> define the complete web site in IIS. The Directory attribute of Web Site element is set to INSTALLLOCATION i.e. C:Program FilesMyWebSite which is our target location to copy the compiled ASP.NET files to run our Web Site.

The bindings IP, PORT and Host Header for our web site are specified by <iis:WebAddress/> element, and the mapping between the application pool MyWebSite_AppPool and the site is defined by <iis:WebApplication/> . The Default Dcoument and the Authentication are specified by <iis:WebDirProperties/>.

So we have defined all the components (MySite_root_Files, MySite_bin_Directory, and MyWebSite_IISConfigure) that need to be installed on to the target server by our installer. But we know that every installer needs at least one feature which is a set of components that define one complete install feature i.e. our Web Site in this case. We have to define it using the feature element.

  <Feature Id="ProductFeature" Title="My WebSite" Level="1">
     <!-- add the components comprise of this feature -->
     <ComponentRef Id="MySite_root_Files"/>
     <ComponentRef Id="MySite_bin_Files"/>
     <ComponentRef Id="MyWebSite_IISConfigure"/>
  </Feature>

That is it. We have completed authoring the installer package for our Web Site. Upon building the entire solution again our Set up project reads the compiled ASP.NET files from our Web Deployment Project out put folder and embeds them into a Windows Installer package which is created in the out put directory of our setup project.

 

clip_image002[4]

Fig 5: Installer package in Setup project output location

We just need to copy this installer package to the target server and double click and wait for the job to be done.

clip_image004[4]

Fig 6: while installing our setup file

Once the install is complete, open the IIS Manager to see that our web site running.

Summary:

The web deployment using WIX is simple, flexible, and gives a overall great web deployment experience.

 

Hope it helps

– Ranjith


26 responses to “Automating Web Deployment using Windows Installer XML (WIX)”

  1. Thanks a lot, it helped… But there is one problem, when you uninstall the wix package the “Default web site” web site node will get deleted. so i did one work around to overcome issue: i.e; add “Permanent=”yes”” in tag for web site and virtual directory

    Sample code:

  2. Hi Vishwanath,

    Thanks for visiting and commenting. Glad to hear that it helped. You are the first commentor on my blog.

    Could you share your website definition WIX code?. I have done an uninstall and it did not touch my Default Web Site.

    🙂 ranjith 🙂

    • Wix has SQL Extension which can be used to work with SQL Scripts. I will do a post on it sometime later. Contact me offline if you need immediate help.

      – Ranjith

      • Thanks, I looked into it. There’s one more question how do I automate the process of adding files under the component MySite_root_Files. I have more than 1000 files / images etc. Is there a VS plugin that will automatically traverse thru the folder structure and add the entries.
        Thanks

  3. Automating Web Deployment using Windows Installer XML (WIX) « Ranjith Kumar S’s blog…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

    • Hi Brian.
      Thanks for visiting. The Generated Setup File can be deployed on to any server with IIS installed on it. Please let me know if it does not answer you.

      Ranjith.

    • Can you share the code. I tried Heat before without any luck.
      Is it advisable to have just one component for all content files or each file becomes a component.

      Thanks
      Rakesh

      • Hi Ranjith, first of all thanks for this post.. I just tried the steps that you have mentioned but the when i building the entire solution at the last stagegetting the error saying “Illegal characters in path”. Please help me on this.

  4. if I create a virtual directory under the existing site other than the default website, it is creating , but with apppool as default apppool not the application pool of the website , can you please tell me what is the reason?
    It is very urgent issue for me. is there any problem with WIX 3.5 ?

  5. Hello,

    Could you provide me some guidance to do updates to a .json file instead of a configuration file like web or application config.

    Thanks,
    Krishna

  6. Sir i am a student. please guide me. this is the task assigned to me in term project.
    Sir i have added asp.net simple web application then i right click on this web application and i don’t find web development project. my question is how to add web development project which name in your example is (MyWebsite_deploy) where to find this?

  7. Hello
    I want help in automatic detection of sql server instance name.
    so that it will automatically change connection string in web.config file. My wix code is working properly but only thing I want is SQL Server instance name so that I do not have to manually change it in web.config after deploy.

  8. The website created using WiX is not displaying IP binding properly. I want to create site like *:Portnumber in IIS. With WixIISExtension this is not working.

Leave a Reply

Your email address will not be published. Required fields are marked *