Background: I have a Wix installer where a virtual directory gets created in an existing IIS website. The virtual directory is created (it doesn't exist before the install) but the IIS website should already be created (user just picks a website to install to in a ListBox).
The problem: On uninstall, the Physical Path of the IIS website that got installed to becomes blank, no value for that attribute. Below is a pared down version of my main wix file. I'm not sure why the uninstall is affecting the IIS website, but any thoughts are appreciated.
Notes: I'm on Wix 3.5 and Windows Server 2008 R2, IIS 7.
<Product>
<Property Id='WEBSITE_DESCRIPTION'>
<RegistrySearch Id='RememberPropertyWEBSITE_DESCRIPTION' Root='HKCU'
Key='SOFTWARE\Company\Product' Name='InstalledWebsiteDescription'
Type='raw' />
</Property>
<Property Id='WEBSITE_PORT'>
<RegistrySearch Id='RememberPropertyWEBSITE_PORT' Root='HKCU'
Key='SOFTWARE\Company\Product' Name='InstalledWebsitePort'
Type='raw' />
</Property>
<Component Id='PropertiesToSave' Directory='ApplicationFolder'>
<RegistryValue Root='HKCU' Key='SOFTWARE\Company\Product'
Name='InstalledWebsiteDescription' Value='[WEBSITE_DESCRIPTION]'
Type='string' />
<RegistryValue Root='HKCU' Key='SOFTWARE\Company\Product'
Name='InstalledWebsitePort' Value='[WEBSITE_PORT]'
Type='string' />
<RemoveFolder Id='CleanupApplicationFolder' On='uninstall' />
</Component>
<Directory Id='TARGETDIR' Name='SourceDir'>
<Component Id='TestWebVirtualDirComponent' Guid='12345678-6304-410E-A808-E3585379EADB'>
<CreateFolder />
<iis:WebVirtualDir Id='TestWebVirtualDir' Alias='[WEBSITE_VIRTUALDIR]' Directory='TARGETDIR' WebSite='MyWebsite'>
<iis:WebApplication Id='TestWebApplication' Name='Test' />
</iis:WebVirtualDir>
</Component>
</Directory>
<iis:WebSite Id="MyWebsite" Description="[WEBSITE_DESCRIPTION]" SiteId="*">
<iis:WebAddress Id="AllUnassigned" Port="[WEBSITE_PORT]" />
</iis:WebSite>
<Feature>
<ComponentRef Id='TestWebVirtualDirComponent'/>
<ComponentRef Id='PropertiesToSave'/>
</Feature>
</Product>
WiX IIsExtension recognizes the WebSite by Description attribute and Port attribute of child WebAddress element. So, when you install your application, you set WEBSITE_DESCRIPTION and WEBSITE_PORT in some way. However, when you run uninstall, the mentioned properties are not set, and you get the behavior you described.
The solution to this is to save the required property values to system registry and use RegistrySearch element to read the values and set appropriate properties. This is called "Remember Property" pattern and is perfectly explained by Rob Mensching here.
Related
I have a web application that we install via a Wix MSI project. The web.config includes the authentication nodes below. Everything installs correctly but after installation, I get the error message:
"The configuration section cannot be used at this path". This is due to the configuration locking in applicationHost.config .
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<basicAuthentication enabled="true" />
<windowsAuthentication enabled="false" />
</authentication>
</security>
</system.webServer>
How can I override the applicationHost.config settings during the installation? I do install required Windows Features during the install, but am I missing one?
This is the solution that worked for me, calling appcmd from a custom action, before InstallFinalize.
<CustomAction Id="UnlockAnonymousAuthentication"
Execute="deferred"
Impersonate="no"
Return="check"
Directory="TARGETDIR"
ExeCommand="[SystemFolder]inetsrv\appcmd unlock config /section:anonymousAuthentication" />
<CustomAction Id="UnlockBasicAuthentication"
Execute="deferred"
Impersonate="no"
Return="check"
Directory="TARGETDIR"
ExeCommand="[SystemFolder]inetsrv\appcmd unlock config /section:basicAuthentication" />
<CustomAction Id="UnlockWindowsAuthentication"
Execute="deferred"
Impersonate="no"
Return="check"
Directory="TARGETDIR"
ExeCommand="[SystemFolder]inetsrv\appcmd unlock config /section:windowsAuthentication" />
<InstallExecuteSequence>
<Custom Action="UnlockAnonymousAuthentication" Before="InstallFinalize"><![CDATA[NOT Installed]]></Custom>
<Custom Action="UnlockBasicAuthentication" Before="InstallFinalize"><![CDATA[NOT Installed]]></Custom>
<Custom Action="UnlockWindowsAuthentication" Before="InstallFinalize"><![CDATA[NOT Installed]]></Custom>
</InstallExecuteSequence>
Hope this helps someone.
Here is currently a way to do this directly using the WiX IIS extension WebDirProperties element:
https://wixtoolset.org/documentation/manual/v3/xsd/iis/webdirproperties.html
Something similar to this should work. Notice the critical piece is the WebDirProperties
element that specifies the
AnonymousAccess="yes" BasicAuthentication="no" WindowsAuthentication="no" which modify
the IIS properties you are looking to change during installation.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension" >
<Fragment>
<!-- Install to default web site -->
<iis:WebSite Id="DefaultWebSite" Description='Default Web Site'>
<iis:WebAddress Id="AllUnassigned" Port="80" />
</iis:WebSite>
<!-- References the installation folder specified in the Product.wxs file under the INSTALLFOLDER -->
<DirectoryRef Id="WEB_INSTALLFOLDER">
<!-- Configure virtual dir -->
<Component Id="VirtualDirectoryComponent"
Guid="{INSERT-YOUR-OWN-GUID-2C27-427A-A7B1-DA4DBCC79117}"
KeyPath="yes" >
<iis:WebVirtualDir Id="VirtualDirectory"
Alias="[WEB_DIRECTORY_ALIAS]" Directory="WEB_INSTALLFOLDER"
WebSite="DefaultWebSite">
<iis:WebDirProperties Id="VirtualDirectoryProperties"
AnonymousAccess="yes" BasicAuthentication="no"
WindowsAuthentication="no" />
<iis:WebApplication
Id="MyWebApplication"
Name="MyWebApplication" />
</iis:WebVirtualDir>
</Component>
</DirectoryRef>
</Fragment>
</Wix>
I am using Wix 3.8 to create an MSI installer for a Visual Studio project I have created. I followed this simple tutorial but even with this simply Wix project I am getting errors. Here is My
I have added my VS2012 project as a reference to my Wix Installer.
Here is my Product.ws file:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'
xmlns:iis='http://schemas.microsoft.com/wix/IIsExtension'>
<Product Id="*" Name="MyProjectInstaller2" Language="1033" Version="2.0.0.0" Manufacturer="Company" UpgradeCode="7f5b63be-bdad-4cc9-b4df-b3f1648c0539">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="MyProjectInstaller2" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="MyProjectInstaller2" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<!-- <Component Id="ProductComponent"> -->
<File Source="$(var.MyProject.TargetPath)" />
<!-- </Component> -->
</ComponentGroup>
</Fragment>
</Wix>
When I compile this, I get the following error:
The ComponentGroup element contains an unexpected child element 'File'.
I have searched the bowels of the internet for a solution to this very basic problem. Why is VS2012 not recognising the element?
You should follow next hierarchy: ComponentGroup -> Component -> File and etc. In your example i suggest to you to put File element into separated component and then add this component into ComponentGroup. Try something like this:
<Component Directory="YOUR-DIRECTORY" Guid="your-guid" Id="SomeComponent">
<File Source="$(var.MyProject.TargetPath)"/>
</Component>
<ComponentGroup Directory="INSTALLFOLDER" Id="ProductComponents">
<ComponentRef Id="SomeComponent"/>
</ComponentGroup>
Read the TODO comment right above your <File Source>
You need to remove the comments around <Component Id="ProductComponent"> and </Component>.
i try create a new web-site using wix installation. it's ok there is no problem but i cannot assign a new or existing web app pool to new web-site. iis:website tag does not contains WebAppPool attribute. How can i assign web app pool to web-site. You can see my code bellow.
thanks for helping.
<Component Id="WEB_SITE_CONFIGURE_COMPONENT" Guid="{35087032-D049-48C8-BCAD-1FEFD0C06A25}" NeverOverwrite="yes" Shared="yes" Permanent="yes" Transitive="yes">
<Condition><![CDATA[WEBSITE_INSTALLTYPE<>2]]></Condition>
<CreateFolder Directory="WEBSITE_FOLDER"/>
<iis:WebSite Id="WEB_SITE" Description="[WEBSITE_NAME]" SiteId="*" Directory="WEBSITE_FOLDER" ConfigureIfExists="yes" AutoStart="yes" StartOnInstall="yes">
<iis:WebAddress Id="AllUnassigned" Port="[WEBSITE_PORT]" />
</iis:WebSite>
<RegistryValue Root="HKLM" Key="$(var.DefaultRegistryKey)" Name="ConfigSite" Value="1" Type="string"></RegistryValue>
</Component>
<Component Id="WEBAPP_POOL_CONFIGURE_COMPONENT" Guid="{316738A6-26A2-4C14-9AB9-B2066E3FA288}" KeyPath="yes" Permanent="yes" Transitive="yes">
<Condition><![CDATA[(WEBSITE_INSTALLTYPE=0) OR (USE_CUSTOM_WEBSITE_FOLDER=1)]]></Condition>
<iis:WebAppPool Id="APP_POOL" Name="[WEBAPP_POOL_NAME]" ManagedPipelineMode="Classic" ManagedRuntimeVersion="v4.0"/>
<RegistryValue Root="HKLM" Key="$(var.DefaultRegistryKey)" Name="ConfigPool" Value="1" Type="string"></RegistryValue>
</Component>
<Component Id="WEPAPP_CONFIGURE_COMPONENT" Guid="{F95B024E-B6B6-4E6C-AC35-9B1086FC3521}" Transitive="yes">
<Condition><![CDATA[(WEBSITE_INSTALLTYPE<>2) AND ((WEBSITE_INSTALLTYPE=0) OR (USE_CUSTOM_WEBSITE_FOLDER=1))]]></Condition>
<iis:WebVirtualDir Id="VIRTUAL_DIR" Alias="[WEB_APP_NAME]" Directory="WWW_FOLDER" WebSite="WEB_SITE">
<iis:WebApplication Id="WEB_APP" Name="[WEB_APP_NAME]" WebAppPool="APP_POOL"/>
</iis:WebVirtualDir>
<RegistryValue Root="HKLM" Key="$(var.DefaultRegistryKey)" Name="ConfigVirtualDir" Value="1" Type="string"></RegistryValue>
</Component>
With the help of the following articles I have come up with a working installer in which a new AppPool can be created or an existing AppPool can be selected.
Creating a Web Application Installer with WIX 3.5 and Visual Studio 2010–Part 1
Web Application Installer in WiX
WiX and DTF: Using a Custom Action to list available web sites on IIS
Installing a Web Application to an Existing IIS Website using Wix3
In short:
Create a Website element in your Product element:
<Product>
<iis:WebSite Id="SelectedWebSite" Description="[WEBSITE_DESCRIPTION]" Directory="INSTALLFOLDER" SiteId="[WEBSITE_ID]">
<iis:WebAddress Id="AllUnassigned" Port="80" />
</iis:WebSite>
</Product>
Create an Include WebSites.wxi with the following content:
<?xml version="1.0" encoding="utf-8"?>
<Include>
<Property Id="WEBSITE_DESCRIPTION">
<RegistrySearch Id="WebSiteDescription" Name="WebSiteDescription" Root="HKLM" Key="SOFTWARE\!(loc.CompanyName)\[ProductName]\Install" Type="raw" />
</Property>
<Property Id="WEBSITE_ID">
<RegistrySearch Id="WebSiteID" Name="WebSiteID" Root="HKLM" Key="SOFTWARE\!(loc.CompanyName)\[ProductName]\Install" Type="raw" />
</Property>
<Property Id="WEBSITE_PATH">
<RegistrySearch Id="WebSitePath" Name="WebSitePath" Root="HKLM" Key="SOFTWARE\!(loc.CompanyName)\[ProductName]\Install" Type="raw" />
</Property>
<Property Id="WEBSITE_VD">
<RegistrySearch Id="WebSiteVD" Name="WebSiteVD" Root="HKLM" Key="SOFTWARE\!(loc.CompanyName)\[ProductName]\Install" Type="raw" />
</Property>
<CustomTable Id="AvailableWebSites">
<Column Id="WebSiteID" Category="Identifier" PrimaryKey="yes" Type="int" Width="4"/>
<Column Id="WebSiteDescription" Category="Text" Type="string" PrimaryKey="no"/>
<Column Id="WebSitePath" Category="Text" Type="string" PrimaryKey="no" Nullable="yes"/>
<Row>
<Data Column="WebSiteID">0</Data>
<Data Column="WebSiteDescription">Dummy</Data>
<Data Column="WebSitePath"></Data>
</Row>
</CustomTable>
</Include>
Create the CustomAction described here.
Create a wxs file with your AppPool:
<?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">
<Fragment>
<Component Id="WebVirtualDirComponent" Guid="PUT-GUID-HERE" Directory="INSTALLFOLDER" KeyPath="yes">
<iis:WebAppPool
Id="YourAppPoolName"
Name="[VD][WEBSITE_ID]"
ManagedRuntimeVersion="v4.0"
IdleTimeout="0"
RecycleMinutes="0"
ManagedPipelineMode="integrated"/>
<iis:WebVirtualDir Id="VDir" Alias="[VD]" Directory="INSTALLFOLDER" WebSite="SelectedWebSite">
<iis:WebApplication Id="NotizBrowserWebApp" WebAppPool="YourAppPoolName" Name="[VD][WEBSITE_ID]" />
<iis:WebDirProperties Id="NotizBrowserProps" AnonymousAccess="no" WindowsAuthentication="yes" DefaultDocuments="-" Execute="yes" Script="yes" Read="yes"/>
</iis:WebVirtualDir>
</Component>
</Fragment>
</Wix>
Late answer, but hopefully someone will be benefited with this.
You don't need a CustomAction to make this work.
It is simple like this:
<Component Id="WebSite" Guid="PUT-YOUR-GUID-HERE">
<CreateFolder/>
<iis:WebSite Id="WebSite" Directory="WebSiteRoot" Description="[WEBSITEDESCRIPTION]" >
<iis:WebApplication Id="WebSiteApplication" Name="[WEBSITEDESCRIPTION]" WebAppPool="MyAppPool" />
</iis:WebSite>
<iis:WebAppPool Id="MyAppPool" Name="[APPPOOLNAME]" ManagedRuntimeVersion="v4.0"/>
</Component>
You need to update the "Internal" WebApplication of the WebSite.
You don't need to have the "WebSite Description" and "WebApplication Name" equal, but that will help you to understand what is going on.
I am building an installer using wix for several .net web applications. I have two features, one of which installs several virtual directories / applications under default web site in IIS. The second feature creates a separate website with a single virtual directory.
The problem is when I install both features, the virtual directories (from feature 1) under default web site are not removed during the uninstall. The strange part is that if I just install feature 1 (exclude feature 2) the uninstall works properly for feature 1 and the virtual directories are removed.
I am new to wix, I'm guessing something is wrong with my product.wxs or there is something Im not understanding. Thoughts?
Here is a sample snippet from my product.wxs file :
<Feature Id="feature1" Title="feature1" Description="feature 1 description" Level="1" ConfigurableDirectory="INSTALLDIR" Display="expand">
...
<ComponentGroupRef Id="IIS_Feature1" />
</Feature>
<Feature Id="feature2" Title="feature2" Description="feature 2 description" Level="1" ConfigurableDirectory="INSTALLDIR" Display="expand">
...
<ComponentGroupRef Id="IIS_Feature2" />
</Feature>
<Directory Id="TARGETDIR" Name="SourceDir">
...
<Directory Id="ROOT_DRIVE">
<Directory Id="Inetpubdir" Name="inetpub">
<Directory Id="wwwrootdir" Name="wwwroot" />
<Directory Id="wwwrootcustom" Name="wwwroot-custom" />
</Directory>
</Directory>
</Directory>
<ComponentGroup Id="IIS_Feature1">
<Component Id="IIS_WebApp1" Guid="some-guid-1" Directory="wwwrootdir" KeyPath="yes">
<iis:WebVirtualDir Id="WebApp1VirtualDir" Alias="webapp1" WebSite="DefaultWebSite" Directory="WEBAPP1DIR">
<iis:WebApplication Id="WebApp1IISApplication" Name="webapp1" />
</iis:WebVirtualDir>
</Component>
<Component Id="IIS_WebApp2" Guid="some-guid-2" Directory="wwwrootdir" KeyPath="yes">
<iis:WebVirtualDir Id="WebApp2VirtualDir" Alias="webapp2" WebSite="DefaultWebSite" Directory="WEBAPP2DIR">
<iis:WebApplication Id="WebApp2IISApplication" Name="webapp2" />
</iis:WebVirtualDir>
</Component>
<Component Id="IIS_WebApp3" Guid="some-guid-3" Directory="wwwrootdir" KeyPath="yes">
<iis:WebVirtualDir Id="WebApp3VirtualDir" Alias="webapp3" WebSite="DefaultWebSite" Directory="WEBAPP3DIR">
<iis:WebApplication Id="WebApp3IISApplication" Name="webapp3" />
</iis:WebVirtualDir>
</Component>
</ComponentGroup>
<ComponentGroup Id="IIS_Feature2">
<Component Id="IIS_WebApp4" Guid="some-guid-4" Directory="wwwrootcustom" KeyPath="yes">
<iis:WebSite Id="WebApp4Site" Description="Web App 4 Site" Directory="wwwrootcustom" AutoStart="yes">
<iis:WebVirtualDir Id="WebApp4VirtualDir" Alias="webapp4" Directory="WEBAPP4DIR">
<iis:WebApplication Id="WebApp4IISApplication" Name="webapp4" />
</iis:WebVirtualDir>
<iis:WebAddress Id="WebApp4SiteAddr" Secure="yes" Port="443"/>
</iis:WebSite>
</Component>
</ComponentGroup>
This issue was discovered during early development of my installer. As more development work was done and other issues resolved, I am no longer seeing this behavior.
I never really figured out exactly what was happening, but I have noticed during testing if one or more things are awry with the installer, certain (seemingly unrelated) components will be left behind during the uninstall...
I have a hierarchy of Directory elements in a WiX script.
I also have a component that creates a virtual directory (using IIS:WebVirtualDir), which points to the root of my Directory hierarchy.
How do I change a property (e.g. AnonymousAccess) of a subfolder of the virtual directory, e.g.
MyVirtualDir <<< this is the virtual directory root
MyVirtualDir\MySubFolder <<< this is the subfolder for which I wish to change a property using WebDirProperties
Please note that I do not wish to create a new virtual directory for the subfolder. I only wish to change a few security settings.
The current script is too big to post here, but take a look at the WiX tutorial: 5.3 Web Directory. Suppose in that example that there was another Directory element named "MySubFolder" nested within the "InstallDir" element. What would then be the next step in order to set properties for "MySubFolder" without turning it into a virtual directory?
Sample code for the IIS:Web element seems to be hard to come by, but after some trial and error, I think I found a solution:
Create the folder as normal in the Directory hierarchy:
<Directory Id='blahDir' Name='blah'>
<Component Id ='CreateBlah' Guid='B1976E1A-DEB1-4FBB-A5AB-4AA60930D2DC'>
<CreateFolder />
</Component>
</Directory>
Create an IIS:WebDirProperties element (in this case, some random values for testing):
<IIS:WebDirProperties Id="ReadAndExecute" Read="yes" Write="yes" Script="yes" Execute="yes" AnonymousAccess="yes" Index="no" LogVisits="no" />
Create an IIS:WebDir component pointing to the folder and the WebDirProperties element:
<Component Id='TestWebDir' Guid='8ED05357-1AAE-49F2-8C66-8813583C8157'>
<IIS:WebDir WebSite='DefaultWebSite' Id='MyWebDir' Path='Test/blah' DirProperties='ReadAndExecute' />
</Component>
The entire sample, adapted from the WiX tutorial, can be found below:
<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:IIS="http://schemas.microsoft.com/wix/IIsExtension">
<Product Name='Foobar 1.0' Id='48A3DF7A-E1C3-48BE-91D9-4D7368740A78' UpgradeCode='F8ABBBC9-0696-4FA9-A0DC-C9368E858A76'
Language='1033' Codepage='1252' Version='1.0.0' Manufacturer='Acme Ltd.'>
<Package Id='*' Keywords='Installer'
Description="Acme's Foobar 1.0 Installer"
Comments='Foobar is a registered trademark of Acme Ltd.' Manufacturer='Acme Ltd.'
InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />
<Icon Id="AddRemoveProgram.ico" SourceFile="AddRemoveProgram.ico" />
<Property Id="ARPPRODUCTICON" Value="AddRemoveProgram.ico" />
<Media Id='1' Cabinet='Sample.cab' EmbedCab='yes' DiskPrompt="CD-ROM #1" />
<Property Id='DiskPrompt' Value="Acme's Foobar 1.0 Installation [1]" />
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder' Name='PFiles'>
<Directory Id='InstallDir' Name='Acme'>
<Directory Id='blahDir' Name='blah'>
<Component Id ='CreateBlah' Guid='B1976E1A-DEB1-4FBB-A5AB-4AA60930D2DC'>
<CreateFolder />
</Component>
</Directory>
<Component Id='default.htmlComponent' Guid='E2FC2FC2-96A2-4BE5-BBCB-7184D9AAACA0'>
<File Id='default.htmFile' Name='default.htm' KeyPath='yes' DiskId='1' Source='default.htm' />
</Component>
</Directory>
</Directory>
<Component Id='TestWebVirtualDirComponent' Guid='B4E73F80-875C-487A-BC57-A568732F03A3'>
<IIS:WebVirtualDir Id='TestWebVirtualDir' Alias='Test' Directory='InstallDir' WebSite='DefaultWebSite'>
<IIS:WebApplication Id='TestWebApplication' Name='Test' />
</IIS:WebVirtualDir>
</Component>
<Component Id='TestWebDir' Guid='8ED05357-1AAE-49F2-8C66-8813583C8157'>
<IIS:WebDir WebSite='DefaultWebSite' Id='MyWebDir' Path='Test/blah' DirProperties='ReadAndExecute' />
</Component>
</Directory>
<IIS:WebSite Id='DefaultWebSite' Description='Default Web Site'>
<IIS:WebAddress Id='AllUnassigned' Port='80' />
</IIS:WebSite>
<Feature Id='TestFeature' Title='TestFeature' Level='1'>
<ComponentRef Id='CreateBlah'/>
<ComponentRef Id='default.htmlComponent' />
<ComponentRef Id='TestWebDir'/>
<ComponentRef Id='TestWebVirtualDirComponent' />
</Feature>
<IIS:WebDirProperties Id="ReadAndExecute" Read="yes" Write="yes" Script="yes" Execute="yes" AnonymousAccess="yes" Index="no" LogVisits="no" />
</Product>
</Wix>