I use the following Wix code to create a WebApplication in IIS and assign it to a specific Application Pool.
<iis:WebAppPool Id="AppPool_Wcf" Name="$(var.WCF_APP_POOL)" />
<iis:WebSite Id="Web_site" Description="$(var.WEB_SITE_DESCRIPTION)" SiteId="[SITEID]">
<iis:WebAddress Id="Web_Address" Port="*"/>
</iis:WebSite>
<DirectoryRef Id="TARGETDIR">
<Directory Id="SITEPATH">
<Directory Id="WCF_VIRT_DIR" Name="$(var.WCF_VIRT_DIR)">
<Component Id="IIS_Wcf" Guid="$(var.deploy.wcf.guid)" KeyPath="yes">
<iis:WebVirtualDir Id="Wcf_VirtualDir" Alias="$(var.WCF_VIRT_DIR)" WebSite="Web_site" Directory="WCF_VIRT_DIR">
<iis:WebApplication Id="Wcf_Application" Name="$(var.WCF_VIRT_DIR)" WebAppPool="AppPool_Wcf" />
</iis:WebVirtualDir>
</Component>
</Directory>
</Directory>
</DirectoryRef>
App Pool should already exist, as it’s shared with some other applications.
If it doesn’t exist, setup succeeds, assigning Web Application to a mysterious <Invalid Application Pool> (can be seen in web app Properties).
The application even works!
How can I make installation fail if App Pool is not found?
You have to create an immediate custom action for this. For instance, in C#/DTF it could be implemented like this:
[CustomAction]
public static ActionResult FailIfAppPoolNotExist(Session session)
{
DirectoryEntry appPool = new DirectoryEntry(string.Format("IIS://localhost/w3svc/AppPools/{0}", session["APP_POOL_NAME"]));
if (appPool == null)
{
return ActionResult.Failure;
}
return ActionResult.Success;
}
Related
I'm writing a Wix Toolset installer to install an Angular + asp.net core application in IIS on Windows Server 2016. I create a new Website and a new Application Pool. I want to grant full permission to the Application Pool identity on the newly created website folder path.
I followed the step given here : https://www.codeproject.com/Articles/115036/Creating-WIX-Installer-for-ASP-NET-Web-Application? so I have 3 files :
Setup.wxs
IISConfiguration.wxs
WebSiteContent.wxs
I set up the website and permissions in IISConfiguration.wxs.
<DirectoryRef Id="WEBSITE">
<Component Id="WebSiteSiteNameCmp" Guid="{ED376FD7-D4DB-4675-8BF4-1DCC1AF1C66B}" KeyPath="yes" >
<iis:WebSite Id="WebSiteName"
Description='WebSiteName'
Directory="WEBSITE"
AutoStart="no"
ConfigureIfExists="yes"
StartOnInstall="no" >
<iis:WebAddress Id="WebSiteAdressHttps" Port="443" IP="*" Secure="yes"/>
<iis:WebAddress Id="WebSiteAdressHttp" Port="80" IP="*" Secure="no"/>
<iis:WebDirProperties Id="WebSiteProperties" AnonymousAccess="yes"
BasicAuthentication="no" WindowsAuthentication="no" />
<iis:WebApplication Id="WebSiteNameSite" Name="WebSite" WebAppPool="WebSiteAppPool" />
</iis:WebSite>
</Component>
<!-- Configuring app pool -->
<Component Id="WebSiteAppPoolCmp" Guid="{009052A8-19AE-452e-AE34-6DC8E929DA08}"
KeyPath="yes" Permanent="yes" Win64="yes">
<iis:WebAppPool Id="WebSiteAppPool" Name="WebSiteAppPoolName" ManagedPipelineMode="integrated" />
</Component>
<Component Id="WebSitePermissionCmp" Guid="{4425EFB0-A580-44B7-9C04-54EBD2E4ECB1}">
<CreateFolder>
<util:PermissionEx User="IIS AppPool\WebSiteAppPoolName" GenericAll="yes"/>
</CreateFolder>
</Component>
</DirectoryRef>
But then the installer rollsback because the AppPool isn't created yet when trying to set permissions on the folder. I have the following error in my logs :
ExecSecureObjects: Error 0x80070534: failed to get sid for account: IIS AppPool\WebSiteAppPoolName.
What should I do to set the permissions at the "good" time ?
I finally used the custom action solution with icalcs to manage the permissions on the newly created application pool. This is what I add in my Setup.wxs :
<CustomAction Id='AppPoolPermission' Directory='WEBSITE'
ExeCommand='"[SystemFolder]icacls.exe" "[INSTALLDIR]." /grant "IIS AppPool\WebSiteAppPoolName:(OI)(CI)F" /T' Return='check'/>
<InstallExecuteSequence>
<Custom Action='AppPoolPermission' After='InstallFinalize' />
</InstallExecuteSequence>
I also removed the WebSitePermissionCmp from IISConfiguration.wxs.
It's not the ideal solution but for me it works. I don't know if this can be achieved only with WIX without custom action.
Another post concerning this issue : How to specify the AppPool Identity in a WiX Permission Element?
I don't fully understand the answer but it also seem to be using custom actions.
I try to learn how to do an installer with WIX on Visual Studio 2012, First I create an HelloWorld Project to test WIX and to do an easy configuration. But I have an error during the building : It says me :
"Failed to open the database. During validation, this most commonly happens when attempting to open a database using an unsupported code page or a file that is not a valid Windows Installer database. Please use a different code page in Module/#Codepage, Package/#SummaryCodepage, Product/#Codepage, or WixLocalization/#Codepage; or make sure you provide the path to a valid Windows Installer database. light.exe 0 1 SetupProject1"
I see several solution like change XML's encoding, switch utf-8 by utf-16. And I also try to delete the encoding statement. But it changes nothing.
Here is my WIX XML :
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="54612752-7163-4B36-8CA6-01615090CD7F" Name="WIXTestSetup" Language="1033" Codepage="1252" Version="1.0.0.0" Manufacturer="MyCompany Ltd."
UpgradeCode="1756bfd5-c713-412a-9524-fb1b72886116">
<Package Id="*" Keywords="Installer" Description="My WIXTest Installer" Languages="1033" SummaryCodepage="1252" InstallerVersion="200"
Compressed="yes" InstallScope="perMachine" Comments="WIXTest Installer is a registered trademark of MyCompany and Co.Ltd" />
<Media Id="1" Cabinet="Sample.cab" EmbedCab="yes" DiskPrompt="CD-ROM #1" />
<Property Id="DiskPrompt" Value="WIXTestSetup Installation [1]"/>
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<Feature Id="ProductFeature" Title="WIXTestSetup" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="MyCompany" Name = "MyCompany" >
<Directory Id="INSTALLFOLDER" Name="WIXTestSetup" />
</Directory>
</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="MainExecutable" Guid="4BFF8919-9C07-4BBE-BD1C-46AB49524566">
<!-- TODO: Insert files, registry keys, and other resources here. -->
<File Id="WIxTestExe" Name ="WIXTest.exe" DiskId="1" Source="D:\PROJETS VISUAL STUDIO\Projects\MyFirstWIXProject\MyFirstWIXProject\bin\Debug\MyFirstWIXProject.exe" KeyPath="yes" />
</Component>
<Component Id="ProgramFilesFolder" Guid="53B3FC8A-9D2B-4CDD-BE68-D155435C6163">
<RemoveFolder Id="ProgramFilesFolder" On="uninstall"/>
</Component>
</ComponentGroup>
</Fragment>
</Wix>
I also check "CodePage" and "SummaryCodePage" but I've not resolve the build problem.
I've tried that too : WiX ICE validation errors
Have you some Idea to fix it ?
In the database validation step, light.exe tries to reopen the MSI file for read/write access While anti virus scanning the new msi file that been created.
Try to do the following:
Exclude the temporary directory from the real-time virus scan.
Adding English input language in Windows' regional settings.
Disable the ICE validation. Go to the wix Project Properties, Tool Settings, then checked "Suppress ICE validation".
You can check discussion related to this topic, here:
Error LGHT0301: Failed to open the database
I have an installer which configures 2 websites, one of which has some applications under the root site. The top level site is configured for Windows Authentication only, as below:
<iis:WebSite Id="WebSite"
Description="Application"
Directory="WEBSITE_INSTALLLOCATION"
AutoStart="yes"
ConfigureIfExists="yes"
StartOnInstall="yes">
<iis:WebAddress Id="AllUnassigned" Port="80" />
<iis:WebApplication Id="WebApplication"
Name="Console"
WebAppPool="WebAppPool"/>
<iis:WebDirProperties Id="WebProperties"
AnonymousAccess="no"
WindowsAuthentication="yes"
AuthenticationProviders="NTLM,Negotiate"/>
</iis:WebSite>
Other (optional) components in the installer then declare applications/virtual directories as follows:
<iis:WebVirtualDir Id="HelpWebSite" Alias="Help" Directory="ApexHelpDir" WebSite="WebSite">
<iis:WebApplication Id="HelpApp" Name="Help" WebAppPool="WebAppPool"/>
<iis:WebDirProperties Id="HelpProps" AnonymousAccess="yes" WindowsAuthentication="no"/>
</iis:WebVirtualDir>
The behaviour I'm seeing is what I'd expect 9/10 times, but intermittently the installer will install the "Website" site with both anonymous authentication and windows authentication, rather than just the Help application with anonymous authentication. The only explanation for this that I can think of is that the act of adding a virtual directory/application underneath a root site occasionally causes the root to inherit the child authentication settings as well as its own.
Note: I tried to raise this as a bug on the wixtoolset.org site, but kept getting an error when trying to do so.
Alternatively, you can write a batch script to create a website and call from WIX as custom action.
Batch file
%systemroot%\system32\inetsrv\appcmd.exe add site /name:YourWebSite /PhysicalPath:%systemdrive%\inetpub\wwwroot /bindings:http/*:80:
WIX(product.wxs)
<CustomAction Id="CreateWebsite" Execute="deferred" Impersonate="no" Return="check" Directory="TARGETDIR" PatchUninstall="no" ExeCommand="Batchfilepath" />
<InstallExecuteSequence>
<Custom Action="CreateWebsite" Before="InstallFinalize">NOT Installed AND NOT PATCH</Custom>
</InstallExecuteSequence>
Change your ExeCommand attribute value to point to the correct batch file path.
The workaround for me was to disable Anonymous Authentication at the server level.
It seems that when this flakiness occurs it does inherit the setting from the server level, although I've no idea why it only happens sometimes.
Here's the Powershell script:
Set-WebConfigurationProperty -Filter "/system.webServer/security/authentication/anonymousAuthentication" -Name Enabled -Value False -PSPath IIS:\
How can I convert a directory under a virtual directory to an application, using WIX?
WIX installs the following Virtual Directory to IIS, and I wish it to also convert the webservice folder to an application.
I could not find a way to do this through WIX or the IIS extension, so I resorted to calling an external command. For future reference, the commands are:
IIS 5
C:\Inetpub\AdminScripts\mkwebdir.vbs -c Localhost -w "Default Web Site" -v "sentry/webservice","{physical path}"
C:\Inetpub\AdminScripts\adsutil.vbs appcreateinproc w3svc/1/root/sentry/webservice
IIS 6
C:\Windows\System32\iisvdir.vbs /create "Default Web Site/Sentry/webservice" webservice "{physical path}"
IIS 7
C:\Windows\System32\inetsrv\appcmd add app /site.name:"Default Web Site" /path:/Sentry/webservice /physicalPath:"{physical path}"
This can be done with the IISExtension, as Daniel Morritt suggests. As it's very difficult to find sample code for this I thought I'd post how I did it.
<!-- Your example uses the default web site. -->
<iis:WebSite Id="DefaultWebSite" Description="Default Web Site" SiteId="*">
<iis:WebAddress Id="DefaultWebAddress" Port="80"/>
</iis:WebSite>
<!-- Web Dir Properties to enable access to a Web Application. -->
<iis:WebDirProperties Id="AnonymousExecuteAndScript"
Read="yes"
Write="no"
Execute="yes"
Script="yes"
AnonymousAccess="yes"
Index="no"
LogVisits="no"/>
<!-- Assumes the presence of this directory reference. -->
<DirectoryRef Id="SentryWebServiceDir">
<Component Id="SentryWebServiceComponent" Guid="{GUID-GOES-HERE}">
<iis:WebVirtualDir Id="SentryWebService"
DirProperties="AnonymousExecuteAndScript"
Alias="Sentry/webservice"
Directory="SentryWebServiceDir"
WebSite="DefaultWebSite">
<!-- Make this virtual directory a web application -->
<iis:WebApplication Id="SentryWebServiceApp" Name="webservice" WebAppPool="DefaultAppPool"/>
</iis:WebVirtualDir>
<!-- Workaround for the need for a KeyPath for this component. -->
<RegistryValue Root="HKLM"
Key="SOFTWARE\YourCompany\Sentry\WebService"
KeyPath="yes"
Value="1"
Type="binary"
Name="Installed"
Id="SentryWebServiceInstalled"/>
</Component>
</DirectoryRef>
All of the above can be nested in a <Fragment> element.
You can add a reference to the WiX IISExtension to your project and create one using this.
A good example of this can be found here: Using WiX to create an IIS virtual directory
I have tested this approach, and it works:
http://www.mail-archive.com/wix-users#lists.sourceforge.net/msg04374.html
It says to put the whole path in the Alias, for example
<iis:WebVirtualDir Id="VIRTDIR_Sentry_webservice"
Directory="WebService"
Alias="Sentry/webservice"
WebSite="SITE_Default"> ...
I have a WiX installer which sets up a couple of root IIS websites each of which has a number of WebApplications. We have a separate AppPool for each root and put each of the WebApplications into that AppPool.
Unfortunately I can't find a way of making sure the WebSites go into their required AppPools and WiX insists on putting them in DefaultAppPool.
Am I missing anything here?
<Component Id="INPUT" Guid="{43302D85-55B5-4C99-8C07-8AF5ED419E0A}" Directory="dirBBD4B479DF2AD0441616B5EB11867FA6" KeyPath="yes">
<iis:WebAppPool Id="INPUTPool" Name="RCMInput" ManagedPipelineMode="integrated" ManagedRuntimeVersion="v4.0"/>
</Component>
<Component Id="INPUTSITE" Directory="dirBBD4B479DF2AD0441616B5EB11867FA6" Guid="{E508497A-C485-4EB8-8A91-4299BD46291B}" KeyPath="yes">
<iis:WebSite Id="INPUTROOT" Description="RCMInput" Directory="dirBBD4B479DF2AD0441616B5EB11867FA6" AutoStart="yes" >
<iis:WebAddress Id="INPUTROOTADDRESS" IP="[RCMINPIP]" Port="443" Secure="yes" Header="[RCMINPHOST]" />
<iis:WebVirtualDir Id="INPUTVD" Alias="InputApp" Directory="dir0AC030D54BBE340DFFCC71C2724F6BF1">
<iis:WebApplication Id="INPUTWEBAPP" Name="InputApp" WebAppPool="RCMInpAppPool">
<iis:WebApplicationExtension CheckPath="no" Extension="svc" Executable="[NETFRAMEWORKROOT]v2.0.50727\aspnet_isapi.dll" Verbs="GET,HEAD,POST,PUT,DELETE"/>
</iis:WebApplication>
</iis:WebVirtualDir>
<iis:WebVirtualDir Id="INPUTVD2" Alias="Administration" Directory="dir78ADFB9F5CBB65D9A3E21EAB7F4C5911">
<iis:WebApplication Id="INPUTWEBAPP2" Name="Administration" WebAppPool="RCMInpAppPool">
<iis:WebApplicationExtension CheckPath="no" Extension="svc" Executable="[NETFRAMEWORKROOT]v2.0.50727\aspnet_isapi.dll" Verbs="GET,HEAD,POST,PUT,DELETE"/>
</iis:WebApplication>
</iis:WebVirtualDir>
</iis:WebSite>
</Component>
I would guess that when you reference the AppPool name "RCMInput" in the WebApplication, it cannot resolve it and is defaulting the the Default App Pool. Have you tried running your MSI with logging turned on and see if that gives any extra detail?
From command line
msiexec /i install.msi -L*v install.log
There's a good blog post on deploying web apps in WiX at http://ranjithk.com/2009/12/17/automating-web-deployment-using-windows-installer-xml-wix/ where he defines the AppPool in the same component as the WebApplication.
Not sure if it has changed in 3.6 but for 3.5 when the AppPool is referenced in WebApplication use the Id, instead of using RCMInpAppPool use INPUTPool.
Here's an excellent example
I was having the same problem, but I finally find a solution for it. Instead of nesting a WebApplication (which is referencing your app pool) inside a WebVirtualDir, put it directly inside your website. So, if you have this:
<iis:WebSite Id='WebSite' Description='My Website' Directory="WebsiteDir">
<iis:WebAddress Id='WebAddress' Port='80' />
<iis:WebVirtualDir Id="VirtualDir" Alias="mywebsite" Directory="WebsiteDir">
<iis:WebApplication Id="WebApplication" Name="MyWebApplication" WebAppPool="MyWebAppPool" />
</iis:WebVirtualDir>
</iis:WebSite>
Replace with this:
<iis:WebSite Id='WebSite' Description='My Website' Directory="WebsiteDir">
<iis:WebAddress Id='WebAddress' Port='80' />
<iis:WebVirtualDir Id="VirtualDir" Alias="mywebsite" Directory="WebsiteDir" />
<iis:WebApplication Id="WebApplication" Name="MyWebApplication" WebAppPool="MyWebAppPool" />
</iis:WebSite>