Convert folder under virtual directory to Application, using WIX - 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"> ...

Related

How to set permission for IIS AppPool identity when creating website in Wix Toolset?

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.

WIX classic ASP website for IIS 8

I wrote the following WIX settings for a classic ASP website for IIS 7:
<iis:WebSite Id='DefaultWebSite' Description='Default Web Site'>
<iis:WebAddress Id="AllUnassigned" Port="80" />
</iis:WebSite>
<Component Id="MyWebSite_IIS7" Guid="xxx" Transitive="yes" >
<Condition><![CDATA[IIS_VERSION >= "IIS 7.0" ]]></Condition>
<CreateFolder/>
<util:User Id="AnonymousUser7" CreateUser="no" Domain="[DOMAIN_NAME]" Name="[USERNAME]" Password="[PASSWORD]" UpdateIfExists="yes" LogonAsService="yes" />
<iis:WebAppPool Id="MyWebSitePool" Identity="other" Name="MyAppPool" ManagedPipelineMode="classic" User="AnonymousUser7" />
<iis:WebVirtualDir Id="MyWebSite_VirtualDir7" Alias="MyWebSite" Directory="INSTALLLOCATION" WebSite="DefaultWebSite" >
<iis:WebApplication Id="TestWebApplication7" Name="MyWebSite" WebAppPool="MyWebSitePool" />
<iis:WebDirProperties Id="MyWebSite_DirProperties7" Read="yes" LogVisits="yes" Index="yes" Script="yes" AnonymousAccess="yes" AnonymousUser="AnonymousUser7" />
</iis:WebVirtualDir>
</Component>
Now using IIS 8, I get HTTP 500 error.
How can I avoid this error using WIX?
Currently I am using Wix 3.7 and no plan to upgrade it to the latest Wix doe to the maintenance issue in our company.
Here is another question.
Someone said if I do the following manual steps, it would work:
1. Go to the website you want to add your application to, then double click on Handler Mappings.
2. Click "Add Script Map" and enter in the following information:
- RequestPath: *.asp
- Executable: C:\Windows\syswow64\inetsrv\asp.dll
- Name: anything
I googled "Add Script Map" and found "appcmd.exe" can add script map, so I tried
C:\windows\system32\inetsrv\appcmd.exe set config /section:handlers /+[name='anything',path='*.asp',verb='*',scriptProcessor='%windir%\syswow64\inetsrv\asp.dll',preCondition='MyWebSite']
Unfortunately this adds script map for all Default Web Site, not for "MyWebSite". Therefore, as a reault, it didn't resolve HTTP 500 error.
Is there any way to add Script Map using any kind of command / app?

Deploying Custom theme in production server

I'm working on a Liferay project.
I'm developing a new Liferay theme using Plugins SDK.
I wonder is it better to use ANT or MAVEN for the project?
Because I managed to run both projects in eclipse.
Also is there any way to deploy automatically the theme in the production server ? (Distant server using tomcat).
For now I'm just using auto deployment, copying the war file to the /deploy file.
Regards
You can add remote server to your Eclipse with Plugins SDK, check https://www.liferay.com/documentation/liferay-portal/6.2/development/-/ai/developing-apps-with-liferay-ide-liferay-portal-6-2-dev-guide-02-en
(this may be helpful for older versions of plugins-sdk)
Assuming that you have ssh access to the remote server, the following ant target can be added and used in /liferay-plugins-sdk/build-common-plugin.xml
<property name="web-server" value="11.11.11.11" />
<property name="web-server-username" value="yourusername" />
<property name="web-server-password" value="yourpassword" />
<property name="web-server-deploy-folder-path" value="/liferay-x.x/deploy" />
<target name="remote-deploy" depends="war">
<echo message="Copying plugin to remote server ..." />
<scp
file="${plugin.file}"
todir="${web-server-username}:${web-server-password}#${web-server}:${web-server-deploy-folder-path}"
trust="true"
/>
<echo message="Done!" />
</target>

WiX not configuring IIS site correctly

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:\

Setting the AppPool of a WebSite element in WiX 3.6

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>

Resources