jon torresdal

  • About
  • Contact

    Architecture community in Norway

    27. September 2008

    Børge Hansen is the latest employee of the DPE team at Microsoft Norway. The DPE team is responsible for MSDN Live, the Norwegian MSDN site, follow up on MS related community activities, Norwegian Developers Conference and are the technical advisors from MS for Norwegian companies. If you’re a developer this is the guys you should get in contact with to get closer to Microsoft and find out what they can do for you.

    Anyway, Børge is DPE’s Architect Advisor. I’ve met him a couple of times and already had some interesting discussions. We’re currently discussing if there is something we can do in the community (like NNUG) to spread the word about architecture and what it means to be an architect. Hopefully something great will come out of this and we as architects (or coming architects) will have a architecture community to throw ideas and discussions at. One of the things I vision is that architecture is less platform dependant, so there should be room for more than just MS technologies in this community.

    WiX and DTF: Using WiX to author MSI installations

    26. September 2008

    This is my second post in my WiX and DTF series for WiX 3.0. Here are some others I’ve written:

    • An introduction
    • Using a bootstrapper to force elevated privileges in Vista
    • Using a Custom Action to list available web sites on IIS

    The source for this WiX demo can be downloaded here: SimpleWebApp.zip

    PS! This demo is only tested on Windows Vista. If you have any issues on other versions of Windows, please let me know.

    Update: There is a bug in the WiX extension for IIS on Vista SP 1 resulting in a install failure (Failed to read IIsWebSite table. (-2147024891)). Currently the only workaround is to run the msi from an elevated command prompt using msiexec /i nameOfInstaller.msi.
    I’ll post an update as soon as I find a better solution or the WiX team publish a bug fix.

    Update2: You can work around the error mentioned above by using the approuch I’ve described here: Using a Bootstrapper To Force Elevated Privileges In Vista

    The short time I’ve used WiX has been a joy. I feel so much more in control over the functionality and possibilities of Windows Installer than with any other tool. I have experience with both InstallShield and Wise, but there I found myself looking around in all corners of the UI and the MSI database to find the functionality I was looking for. However, without the knowledge from these two products the transition to WiX would not have been that easy.

    In WiX everything is at your fingertips, even though it’s XML :-) It is however good if you have a bit of knowledge about Windows Installer and how it works. At first I was skeptical to WiX using XML, but with Visual Studio intellisense and a nice integration for e.g. build functionality, it’s way better than any other xml authoring tool I’ve tried. Saying that, the documentation for WiX is a bit incomplete. This is especially true for WiX 3.0. However, there are other sources of documentation to WiX than their web site. There’s quite a few blog posts out there, the WiX mailing list and a couple of Wiki’s.

    Download and install

    Now down to the essence of WiX; authoring MSI installations. Before you start you need to download WiX and install. In my article I will assume you have Visual Studio installed, but you can certainly do the same things without Visual Studio, though with a bit of extra work.

    After you have installed WiX you should have a few new templates in Visual Studio. I’m using VS 2008, where it looks like this:

    WixProjects

    Creating a new WiX project

    1. File -> New -> Project
    2. Select Project type WiX, Template WiX Project and click OK

    That was that! Not too hard was it? So what do we have now?

    <?xml version="1.0" encoding="UTF-8"?>
    <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
        <Product Id="77da05c4-1644-4bc3-ac14-c0f721fe31fe" Name="WixProject1" Language="1033" Version="1.0.0.0" Manufacturer="WixProject1" UpgradeCode="a897ccc5-1c81-47e0-a837-65c07a72a7bc">
            <Package InstallerVersion="200" Compressed="yes" />
    
            <Media Id="1" Cabinet="WixProject1.cab" EmbedCab="yes" />
    
            <Directory Id="TARGETDIR" Name="SourceDir">
                <Directory Id="ProgramFilesFolder">
                    <Directory Id="INSTALLLOCATION" Name="WixProject1">
                        <!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
                        <!-- <Component Id="ProductComponent" Guid="fc46b1a2-35e9-4a17-896b-80b2daaae567"> -->
                            <!-- TODO: Insert files, registry keys, and other resources here. -->
                        <!-- </Component> -->
                    </Directory>
                </Directory>
            </Directory>
    
            <Feature Id="ProductFeature" Title="WixProject1" Level="1">
                <!-- TODO: Remove the comments around this ComponentRef element and the Component above in order to add resources to this installer. -->
                <!-- <ComponentRef Id="ProductComponent" /> -->
            </Feature>
        </Product>
    </Wix>
    

    We have an installation definition that can generate an msi that does nothing! :-) Let’s modify it to do something useful…

    Adding installer UI

    By default WiX uses the simplest installer UI possible, meaning none but the default shown by Windows Installer. This means if you want your users to interact with your installation, you need to customize it a bit. WiX comes with the following built-in dialog sets that will make this easy:

    • WixUI_Mondo
    • WixUI_FeatureTree
    • WixUI_InstallDir
    • WixUI_Minimal
    • WixUI_Advanced

    While creating the installer I will try to follow best practices for Windows Installer, have it work with Vista and Server 2008, and make it pass the Certified for Windows Vista test cases. That means we need to allow the user to select which folder she wants the application installed to. Which one of the above can help us out with that? You guessed it; WixUI_InstallDir.

    1. Add a reference to WixUIExtension.dll (right click project -> Add referece…)
    2. Add these two lines between the Directory and Feature tags in your Product.wxs file:
            <Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />
            <UIRef Id="WixUI_InstallDir" />
    

    The property WIXUI_INSTALLDIR must be set for the UI to know which directory to use as default. Here I set it to INSTALLLOCATION which is the Id of the directory where the application is being installed. The UIRef tag allow us to reference an external package of UI’s. In this case the WixUI_InstallDir in the WixUIExtension library.

    Changing the installer UI

    In this section we’re going to remove the license agreement dialog from the UI and change the graphics displayed in the Windows Installer wizard.

    WixUI_InstallDir actually includes several dialogs. Among others the license agreement dialog and the install dir dialog. For my installer I don’t want the license agreement, so how do I remove it?

    The easiest way is to download the WiX source and get the wxs file for WixUI InstallDir and make it your own (before you think this is too cumbersome, try it. It’s actually quite fast and simple, and you learn a thing or two by looking at the source files) :

    1. Right click your WiX project -> Add -> New Item…
    2. Select WiX File and give it a name (e.g. MyUI.wxs)
    3. In a text editor, open the file WixUI_InstallDir.wxs found (in the version I’m using) here: …Wix-3.0.4318.0-sources\src\ext\UIExtension\wixlib
    4. Copy the xml
    5. Paste it into your new WiX file (MyUI.wxs)
    6. Comment out the license agreement dialogs (see source below)
    7. Change the navigation targets for Next and Back buttons for WelcomeDlg and InstallDirDlg to not use LicenseAgreementDlg anymore (see source below)

    The next thing I want to do is change the welcome screen and the top banner of the installation with my own graphics. Here’s how:

    1. Add a new folder to your vs project and name it Images
    2. Create two images (if you don’t want to create your own, you can download mine by clicking on links for the images)
      1. msibanner.jpg (493×58)
      2. msiwelcome.jpg (493×312)
    3. Copy your images to the Images folder
    4. Next add the two lines below to your UI file (MyUI.wxs) just below the Fragment node to have the installation use the new images:
            <WixVariable Id="WixUIBannerBmp" Value="Images\msibanner.jpg" />
            <WixVariable Id="WixUIDialogBmp" Value="Images\msiwelcome.jpg" />
    

    Here’s the MyUI.wxs file after the changes:

    <?xml version="1.0" encoding="UTF-8"?>
    <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
        <Fragment>
            <WixVariable Id="WixUIBannerBmp" Value="Images\msibanner.jpg" />
            <WixVariable Id="WixUIDialogBmp" Value="Images\msiwelcome.jpg" />
    
            <UI Id="MyUI">
                <TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
                <TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
                <TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
    
                <Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
                <Property Id="WixUI_Mode" Value="InstallDir" />
    
                <DialogRef Id="BrowseDlg" />
                <DialogRef Id="DiskCostDlg" />
                <DialogRef Id="ErrorDlg" />
                <DialogRef Id="FatalError" />
                <DialogRef Id="FilesInUse" />
                <DialogRef Id="MsiRMFilesInUse" />
                <DialogRef Id="PrepareDlg" />
                <DialogRef Id="ProgressDlg" />
                <DialogRef Id="ResumeDlg" />
                <DialogRef Id="UserExit" />
    
                <Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="3">1</Publish>
                <Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4"><![CDATA[WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
    
                <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
    
                <!-- Changed WelcomeDlg next button to navigate to InstallDirDlg-->
                <!--<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>-->
                <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg">1</Publish>
    
                <!-- Removed LicenseAgreementDlg -->
                <!--
                <Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
                <Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg">LicenseAccepted = "1"</Publish>
                -->
    
                <!-- Changed InstallDirDlg back button to navigate to WelcomeDlg -->
                <!--<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>-->
                <Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
    
                <Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
                <Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2">1</Publish>
                <Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3"><![CDATA[WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
                <Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="4"><![CDATA[WIXUI_INSTALLDIR_VALID="1"]]></Publish>
                <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
                <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
    
                <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1">NOT Installed</Publish>
                <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed</Publish>
    
                <Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
    
                <Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
                <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
                <Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
    
                <Property Id="ARPNOMODIFY" Value="1" />
            </UI>
    
            <UIRef Id="WixUI_Common" />
        </Fragment>
    </Wix>

    If you now build your project you can see how the new installer looks like by running the MSI file which you’ll find in the debug folder of your project.

    Adding files, folders, shortcuts and changing Web.config

    A nice UI for the installer is all good, but without installing anything useful it’s not much point is it? So let’s add some files.

    Adding files

    Since I’m later going to demo how to select which web site to install to (by using a custom action), it’s natural that we’re going to install a web application. I’ve created a very simple web app that has three files: Default.aspx, Web.config and SimpleWebApp.dll. So let’s add them to the installation by changing Product.wxs:

    Add directories, components, files and feature ref’s as shown below:

    <Directory Id="TARGETDIR" Name="SourceDir">
        <Directory Id="ProgramFilesFolder">
            <Directory Id="INSTALLLOCATION" Name="SimpleWebApp">
                <Component Id="Default.aspx" Guid="fc46b1a2-35e9-4a17-896b-80b2daaae567">
                    <File Id="Default.aspx" Name="Default.aspx" Source="$(var.SolutionDir)SimpleWebApp\Default.aspx" DiskId="1" KeyPath="yes" />
                </Component>
                <Component Id="Web.config" Guid="2ED81B77-F153-4003-9006-4770D789D4B6">
                    <File Id="Web.config" Name="Web.config" Source="$(var.SolutionDir)SimpleWebApp\Web.config" DiskId="1" KeyPath="yes" />
                </Component>
                <Directory Id="binFolder" Name="bin">
                    <Component Id="SimpleWebApp.dll" Guid="7FC6DA37-12E5-463d-8E7E-08F73E40CCF2">
                        <File Id="SimpleWebApp.dll" Name="SimpleWebApp.dll" Source="$(var.SolutionDir)SimpleWebApp\Bin\SimpleWebApp.dll" DiskId="1" KeyPath="yes" />
                    </Component>
                </Directory>
            </Directory>
        </Directory>
    </Directory>
    ...
    <Feature Id="ProductFeature" Title="SimpleWebApp" Level="1">
        <ComponentRef Id="Default.aspx" />
        <ComponentRef Id="Web.config" />
        <ComponentRef Id="SimpleWebApp.dll" />
    </Feature>

    One thing to note in is the use of $(var.SolutionDir) in the Source attribute. This is a reference to a Visual Studio variable. In this case the path for the solution directory.

    Adding a shortcut

    Now let’s add a shortcut to the start menu. To do this we need a reference to another WiX component: WixUtilExtension. To get intellisense in VS add the following xml namespace to the Wix node:

    xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"

    And then add this xml:

    <Directory Id="TARGETDIR" Name="SourceDir">
    ...    <Directory Id="ProgramMenuFolder">
            <Directory Id="MyWebAppStartMenuFolder" Name="SimpleWebApp">
                <Component Id="StartMenuFolder" Guid="B3AEC4C4-3F8E-4865-B87A-B750533776B5" >
                    <util:InternetShortcut Id="SimpleWebAppShortcut" Name="SimpleWebApp" Target="http://localhost/SimpleWebApp/Default.aspx" Directory="MyWebAppStartMenuFolder" />
                    <RemoveFolder Id="RemoveStartMenuFolder1" On="uninstall"/>
                    <RegistryKey Root="HKCU" Key="SOFTWARE\torresdal.net\SimpleWebApp\SimpleWebAppShortcut">
                        <RegistryValue Type="string" Value="Default Value"/>
                    </RegistryKey>
                </Component>
            </Directory>
        </Directory>
    </Directory>

    The directory ProgramMenuFolder is a standard directory id for the program menu folder. Under that folder we add another folder for our application; the SimpleWebApp. To add the actual shortcut we need a component. In this component we define the shortcut by using util:InternetShorcut. In addition to this we must make sure to remove the SimpleWebApp folder un uninstall done by using the RemoveFolder action. And last we need to associate the component with a key. Usually components automatically links to a file for its key, but since there is no file here we must provide a registry key instead. This is done using the RegistryKey and RegistryValue actions.

    And since we’ve created a new component we need to add that to the feature:

    <ComponentRef Id="StartMenuFolder" />

    Changing Web.config

    Now let’s do some changes to Web.config during installation. Under the component for Web.config add this xml that will add an element to appSettings in the config file:

    <util:XmlFile Id="AppSettingsAddNode" File="[INSTALLLOCATION]Web.config" Action="createElement" ElementPath="/configuration/appSettings" Name="add" Sequence="1" />
    <util:XmlFile Id="AppSettingsKeyAttribute" Action="setValue" File="[INSTALLLOCATION]Web.config" ElementPath="/configuration/appSettings/add" Name="key" Value="AddedDuringInstall" Sequence="2" />
    <util:XmlFile Id="AppSettingsValueAttribute" Action="setValue" File="[INSTALLLOCATION]Web.config" ElementPath="/configuration/appSettings/add" Name="value" Value="This text was added during installation." Sequence="3" />
    

    The first line will add the ‘add’ node below the appSettings node. The second line will add the ‘key’ attribute and the third line will add the ‘value’ attribute. WiX also provide a util called XmlConfig which is suppose to be customized for .Net config files. However, I was unable to get it to work as expected. Please let me know if you find out how to use XmlConfig instead.

    Adding the web application to IIS

    To work with IIS, WiX has another extension we can use; the IISExtension. Add the reference and define the xml namespace:

    xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension"

    Then add the following xml under the root directory TARGETDIR:

    <Component Id="IISApplication" Guid="FFA12D9C-5AEC-45f8-AA7D-5C4CEC7FA466">
        <iis:WebAppPool Id="SWAAppPool" Name="SWAAppPool" />
        <iis:WebVirtualDir Id="VirtualDir" Alias="[TARGETVDIR]" Directory="INSTALLLOCATION" WebSite="DefaultWebSite">
            <iis:WebApplication Id="SimpleWebAppApp" Name="[TARGETVDIR]" WebAppPool="SWAAppPool" />
            <iis:WebDirProperties Id="WebVirtualDirProperties" Execute="yes" Script="yes" Read="yes" WindowsAuthentication="no" AnonymousAccess="yes" IIsControlledPassword="yes" />
        </iis:WebVirtualDir>
    </Component>

    And also since this is a new component, we need to add it to the feature:

    <ComponentRef Id="IISApplication" />

    We also need to define the default web site which the virtual directory is pointing to:

    <iis:WebSite Id='DefaultWebSite' Description='Default Web Site'>
        <iis:WebAddress Id='AllUnassigned' Port='80' />
    </iis:WebSite>

    The iis:WebAppPool will add a new application pool for this web application. This is strictly not necessary, but I like my web apps to run in its own app pool so I can recycle only that web app without affecting other apps. iis:WebVirtualDir adds a virtual directory to IIS under Default Web Site. In addition to this (since we have an asp.net app) we want to define a web application by using iis:WebApplication. This is set up to use the application pool defined earlier. And the last item is the properties for the virtual directory defined by iis:WebDirProperties. For further details about these items, have a look at the schema reference found in the WiX documentation.

    Giving the installer a proper name

    To have the installer to use Simple Web App as the product name and not WixProject1, change the Name attribute of the Product node like this:

    <Product Id="77da05c4-1644-4bc3-ac14-c0f721fe31fe" Name="Simple Web App" Language="1033" Version="1.0.0.0" Manufacturer="Jon Torresdal" UpgradeCode="a897ccc5-1c81-47e0-a837-65c07a72a7bc">
    

    And also if you want a different name of the msi you can changed that on the properties page of the WiX project. Just set the output name to something else.

    The complete source

    <?xml version="1.0" encoding="UTF-8"?>
    <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension">
        <Product Id="77da05c4-1644-4bc3-ac14-c0f721fe31fe" Name="Simple Web App" Language="1033" Version="1.0.0.0" Manufacturer="Jon Torresdal" UpgradeCode="a897ccc5-1c81-47e0-a837-65c07a72a7bc">
            <Package InstallerVersion="200" Compressed="yes" />
    
            <Media Id="1" Cabinet="WixProject1.cab" EmbedCab="yes" />
            <Property Id="TARGETVDIR" Value="SimpleWebApp"/>
    
            <Directory Id="TARGETDIR" Name="SourceDir">
                <Directory Id="ProgramFilesFolder">
                    <Directory Id="INSTALLLOCATION" Name="SimpleWebApp">
                        <Component Id="Default.aspx" Guid="fc46b1a2-35e9-4a17-896b-80b2daaae567">
                            <File Id="Default.aspx" Name="Default.aspx" Source="$(var.SolutionDir)SimpleWebApp\Default.aspx" DiskId="1" KeyPath="yes" />
                        </Component>
                        <Component Id="Web.config" Guid="2ED81B77-F153-4003-9006-4770D789D4B6">
                            <File Id="Web.config" Name="Web.config" Source="$(var.SolutionDir)SimpleWebApp\Web.config" DiskId="1" KeyPath="yes" />
                            <util:XmlFile Id="AppSettingsAddNode" File="[INSTALLLOCATION]Web.config" Action="createElement" ElementPath="/configuration/appSettings" Name="add" Sequence="1" />
                            <util:XmlFile Id="AppSettingsKeyAttribute" Action="setValue" File="[INSTALLLOCATION]Web.config" ElementPath="/configuration/appSettings/add" Name="key" Value="AddedDuringInstall" Sequence="2" />
                            <util:XmlFile Id="AppSettingsValueAttribute" Action="setValue" File="[INSTALLLOCATION]Web.config" ElementPath="/configuration/appSettings/add" Name="value" Value="This text was added during installation." Sequence="3" />
                        </Component>
                        <Directory Id="binFolder" Name="bin">
                            <Component Id="SimpleWebApp.dll" Guid="7FC6DA37-12E5-463d-8E7E-08F73E40CCF2">
                                <File Id="SimpleWebApp.dll" Name="SimpleWebApp.dll" Source="$(var.SolutionDir)SimpleWebApp\Bin\SimpleWebApp.dll" DiskId="1" KeyPath="yes" />
                            </Component>
                        </Directory>
                    </Directory>
                </Directory>
                <Directory Id="ProgramMenuFolder">
                    <Directory Id="MyWebAppStartMenuFolder" Name="SimpleWebApp">
                        <Component Id="StartMenuFolder" Guid="B3AEC4C4-3F8E-4865-B87A-B750533776B5" >
                            <util:InternetShortcut Id="SimpleWebAppShortcut" Name="SimpleWebApp" Target="http://localhost/SimpleWebApp/Default.aspx" Directory="MyWebAppStartMenuFolder" />
                            <RemoveFolder Id="RemoveStartMenuFolder1" On="uninstall"/>
                            <RegistryKey Root="HKCU" Key="SOFTWARE\torresdal.net\SimpleWebApp\SimpleWebAppShortcut">
                                <RegistryValue Type="string" Value="Default Value"/>
                            </RegistryKey>
                        </Component>
                    </Directory>
                </Directory>
                <Component Id="IISApplication" Guid="FFA12D9C-5AEC-45f8-AA7D-5C4CEC7FA466">
                    <iis:WebAppPool Id="SWAAppPool" Name="SWAAppPool" />
                    <iis:WebVirtualDir Id="VirtualDir" Alias="[TARGETVDIR]" Directory="INSTALLLOCATION" WebSite="DefaultWebSite">
                        <iis:WebApplication Id="SimpleWebAppApp" Name="[TARGETVDIR]" WebAppPool="SWAAppPool" />
                        <iis:WebDirProperties Id="WebVirtualDirProperties" Execute="yes" Script="yes" Read="yes" WindowsAuthentication="no" AnonymousAccess="yes" IIsControlledPassword="yes" />
                    </iis:WebVirtualDir>
                </Component>
            </Directory>
    
            <iis:WebSite Id='DefaultWebSite' Description='Default Web Site'>
                <iis:WebAddress Id='AllUnassigned' Port='80' />
            </iis:WebSite>
    
            <Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />
            <UIRef Id="MyUI" />
    
            <Feature Id="ProductFeature" Title="SimpleWebApp" Level="1">
                <ComponentRef Id="Default.aspx" />
                <ComponentRef Id="Web.config" />
                <ComponentRef Id="SimpleWebApp.dll" />
                <ComponentRef Id="StartMenuFolder" />
                <ComponentRef Id="IISApplication" />
            </Feature>
        </Product>
    </Wix>
    

    Build and install

    That’s it! Now lets build the project and install the application.

    OpenID support

    14. September 2008

    openid I’ve updated my DasBlog to version 2.2.8252.15582 and it has OpenID support! If you have an OpenID you can now use that for posting comments to my blog. I’m not taking the same stand as Aaron Hockley though, refusing to comment on blogs without OpenID support (at least not yet…).

    So why use OpenID except from identifying yourself on my blog? :-) The number one reason as I see it is that you have one ID to identify yourself across multiple web sites. This will remove the need for "forgot your password?" links, your favorite pet etc. Also that you rely on one provider for your id that you trust (hopefully) and don’t have to "give away" passwords, which you probably only have a few of, using them on all the different accounts you’re creating around the Internet.

    When you sign into a site using OpenID you get redirected to your provider for authentication. Here you can choose how much information you want to submit about yourself to the site you’re logging on to. E.g. you may chose to send no information at all, just your name or email etc.

    If you want to know more about OpenID and how it works, check out openid.net. Scott Hanselman has a Weekly Source Code edition of OpenID and also a podcast.

    Don’t have OpenID? I use myOpenId.com where I’ve also added my domain (torresdal.net), allowing me to use that instead of [myname].myopenid.com. My id is jon.torresdal.net. Another popular way of using your ID is to map it to your web site. Below is an example from my web site using myopenid.com:

        <link rel="openid.server" href="http://www.myopenid.com/server" />
        <link rel="openid.delegate" href="http://torresdal.myopenid.com/" />
        <link rel="openid2.local_id" href="http://torresdal.myopenid.com" />
        <link rel="openid2.provider" href="http://www.myopenid.com/server" />
        <meta http-equiv="X-XRDS-Location"
              content="http://www.myopenid.com/xrds?username=torresdal" />
    

    This way I can use blog.torresdal.net as my id. However, one side effect of this is that many blog engines use the name before the dot as your name. If I use my blog url as identifier on e.g. a blog hosted by blogger.com, the comment will say "blog said…", which is not very helpful.

    I mentioned myopenid.com, but there are several other suppliers out there. Just Google openid and you’ll find many.

    PS! All comments to this blog post is expected to use OpenId! :-)

    I’m on Twitter

    12. September 2008

    A few weeks ago my friend Einar Ingebrigtsen sent me a Twitter request, so I sign up. Didn’t do much though, thought I have a look later… Today I picket up the ball and I’m afraid there’s no way back. After browsing/searching around for 15 min and "Follow" friends, I realized how much I’ve missed!

    http://twitter.com/torresdal

    WiX and DTF: Introduction

    3. September 2008

    This is my first post in my WiX and DTF series for WiX 3.0. Here are some others I’ve written:

    • Using WiX to author MSI installations
    • Using a bootstrapper to force elevated privileges in Vista
    • Using a Custom Action to list available web sites on IIS

    Windows Installer XML (WiX)

    The version of WiX I’m going to talk about is v.3.0, currently in beta. In essence WiX is an XML format for writing MSI deployment packages. Much like using InstallShield or Wise to write your installations, you can use WiX to do the same. So why do you want to use XML to author your msi’s? At first I thought: "Ohhh no! Not another XML based authoring tool!" But after doing some more digging, this is one of the scenarios were XML makes sense… kind of. Here’s the benefits I see with WiX compared to traditional MSI tools:

    • It’s perfect for "code" generation, using Nant, TFS etc.
    • WiX is very clean, so it gives you the possibility to author exactly what you need and not have all the general stuff that IS and Wise has pre added to your installation

    Another thing to note is that WiX is open source and it comes from Microsoft (yea, Microsoft HAVE open source projects). Not only that, but this tool got so popular within Microsoft that most of their packages are now moving towards using WiX, and many of them, like Office, already use WiX. That says a lot!

    I’ll get back to using WiX to author msi installations in a later post, but now I want to focus on DTF and how to use it without WiX.

    Deployment Tools Foundation (DTF)

    DTF is among other things a managed (.net) wrapper on top of msi.dll (the windows installer library). DTF makes it possible to write custom actions (CA’s) for MSI installations in C#, VB.net or any other .Net language. If you’re not used to working with MSI installations this might not be a big deal for you, but for me this is fantastic news! Not only that, debugging has now become much easier (or should i say possible).

    Before you only had three options for writing CA’s: C++, VB Script and Java Script. CA’s are custom code you write because there are currently no existing action supported by MS Installer that does what you’re looking for.

    Examples of things you can do with Windows Installer out of the box are:

    • Install/delete/move files
    • Create/delete/change folders
    • Create/delete/change shortcuts
    • Install/remove/start/stop Windows Services
    • Reboots
    • Install/remove ODBC drivers
    • Register/un-register COM/COM+ applications
    • Register/un-register fonts
    • Write/change registry
    • …and so on…

    Check this out for a more complete list.

    However, Windows Installer can’t cover all scenarios, so then you turn to CA’s. Here are some examples I’ve used CA’s for:

    • List SQL Servers
    • List IIS Web Sites
    • Create Web Sites and Virtual Directories
    • Change XML files

    You should however know this; writing good CA’s is difficult and there is a lot of things to take into account. For instance, what happens if your installation fails and starts rolling back? Then you need to make sure that any changes you’ve done to the system with your CA also needs to roll back, meaning you have to have two CA’s, one for adding stuff and one for removing stuff.

    Why not just stick to VB/Java script?

    Using VB and Java scripts has become more and more difficult because of security restrictions, virus programs etc. Many virus programs will not allow you to use Windows Scripting Host (WSH) at all.

    About 2 months ago I did some work on our existing msi packages related to a Microsoft certification program. The requirements for this certification forced me to adopt the best practices that I should have done a long time ago. To avoid the problem with scripting I had two options. Rewrite my CA’s in C++, or in C# using DTF. After digging around it was an easy choice. I went for managed code.

    However, this might not be the right solution for you. Managed code require the .Net framework, so if you don’t know if .Net is present on the computer running your software, you might want to stick to "traditional" CA’s. For me this was not a problem, since all computers (clients and servers) we install on already have .Net pre-installed.

    Next

    Next time I’ll show you how to create a CA for listing available IIS Web Sites on IIS7. This will allow you to choose which web site to install your application under. Until then I suggest you check out WiX/DTF and start thinking if this is something for you.

  • Next Page
  • Page 1 of 2
  • Recent Posts

    • How ConDep came to life
    • Introducing ConDep
    • Lightning Talk: Why you shouldn’t track bugs
    • How Do We Track Bugs? Check In a Failing Test!
    • Stepping Down from NNUG Bergen, Still Chairman of NNUG National
  • Archives

    • March 2013
    • February 2013
    • November 2012
    • January 2012
    • June 2011
    • May 2011
    • September 2010
    • August 2010
    • June 2010
    • April 2010
    • March 2010
    • February 2010
    • January 2010
    • December 2009
    • August 2009
    • July 2009
    • June 2009
    • May 2009
    • April 2009
    • March 2009
    • February 2009
    • January 2009
    • December 2008
    • November 2008
    • October 2008
    • September 2008
    • August 2008
    • July 2008
    • June 2008
    • May 2008
    • April 2008
    • March 2008
    • February 2008
    • January 2008
    • December 2007
    • November 2007
    • October 2007
    • September 2007
    • August 2007
    • July 2007
    • June 2007
    • May 2007
    • April 2007
    • March 2007
    • February 2007
    • January 2007
    • December 2006
    • November 2006
    • October 2006
    • September 2006
  • Categories

    • .Net
    • ADFS
    • Agile
    • Ajax
    • Architecture
    • Articles
    • ASP.NET
    • ASP.NET-MVC
    • Blogging
    • Books
    • BPEL
    • CleanCode
    • CloudComputing
    • Community
    • ContinuousDelivery
    • ContinuousDeployment
    • CSharp
    • DasBlog
    • Database
    • DDD
    • Deployment
    • DevOps
    • DSL
    • Events
    • ExtremeProgramming
    • Fun
    • Gadgets
    • IIS
    • InfoQ
    • Java
    • Kanban
    • Lean
    • Linq
    • MemoryLeaks
    • Microsoft
    • MVC
    • NDC
    • NNUG
    • Other
    • Patterns
    • Performance
    • Scrum
    • Security
    • Silverlight
    • Software
    • TeamManagement
    • TechEd
    • Testing
    • Tools
    • TvGuide
    • Uncategorized
    • Vista
    • VisualStudio
    • WCF
    • Web
    • WebDeploy
    • WIF
    • Windows
    • WiX
    • Work
    • Workflow
  • Meta

    • Log in
    • Entries RSS
    • Comments RSS
    • WordPress.org

Tumblog WordPress Themes by Theme created by Obox