Visual-studio – How to control the AppPool used for deploy through VS & MSDeploy settings

application-poolmsdeployvisual studio

When I build a deploy package for my webapp the package contains an archive.xml file that contains the following:

<createApp
    applicationPool=""
    MSDeploy.applicationPool="1"
    appExists="True"
    MSDeploy.appExists="1"
    ... />

Question:

How can I control the application pool that the webapp gets installed into and, in some cases, create a new application pool? Are there VS settings that I can change to control the above output or otherwise affect how the application pool at deploy time?

What I've found so far:

1. An MSBuild Parameter

According to one SO post I can tell msbuild to use an app pool by adding the following option but I couldn't see any difference in the generated output:

/p:IncludeAppPool=true

2. A parameters.xml file customization

Another post on setting the app pool for msdeploy seems to imply I might be able to modify the generated parameters.xml file so that I can specify the app pool name as an argument to msdeploy. This file exists within the zip package so wouldn't be easy to customize. If I change it to an archive then the file's more easily accessible.

3. A change of VS settings

The Howto deploy a webapp page seems to imply I might need to switch from IIS Express to IIS and then enable some checkboxes. On my project properties page the Include application pool settings used by this Web project checkbox is disabled regardless of the "Include IIS settings as configured in IIS Express" checkbox setting (which I currently have unchecked). I'll try switching to the full IIS next and seeing if that gives me better control.

4. Create an app pool with cscript

It looks like I might be able to create an app pool with a separate tool but I'm not sure if it's TFS-only. It's a tool that I haven't seen before but it may be a capable tool.

5. MSDeploy has an appPoolConfig Provider

MSDeploy's appPoolConfig provider looks promising as I could probably manually setup an application pool and then use that as a sync source, but at least it's only manual once.

Best Answer

I'm also starting to look into the possibilities on how to accomplish this.

I've still some research to do, but I can give you the following pointers:

  1. IncludeAppPool=true enable the AppPoolExtension which also copies the app pool when synching a web site from one location to the other. I guess it will not have an effect when creating a package. Unless maybe if you WAP is run via your local IIS and you include IIS Settings in your package.

  2. Parameters.xml exists in the zip indeed. But if you place a Parameters.xml file in the root of your WAP you can specify your own parameters which will be merged with the one VS creates when packaging.

  3. You can indeed check "Include application pool settings used by this Web project" (in fact: this sets the msbuild property IncludeAppPool to true). The manifest will then hold a entry for creating the app-pool. This is however only possible if you are creating the package from a machine that also locally runs the WAP. This is not an option when working with a build server which is my case

  4. It could be possible to make a batch script to run msdeploy from the commandline and use the AppPool provider to create the apppool. Although this seems a bit clunky to me as I'd like to include the apppool creation inside the manifest of my VS (or build server) generated package

  5. I'm right now investigating if it would be possible to insert the apppoolconfig provide inside my manifest using a wpp.targets file (more info here and here

I might get back to you if I find how to do it.

Edit:

I've found out that there is no way you can package the creation of a new app pool using the appPoolConfig provider. I was forced to write my own provider. I did that based on some (very basic) examples I found and by reverse engineering some of the existing providers. What I basically did was create a wrapper class that calls c:\windows\system32\inetsrv\appcmd and exposed this functionallity as a MSDeploy provider. appcmd is a commandline tool to configure iis, with it you can create apppools... If anyone's interested I could share some of the code...

Hi, another edit

I'm sorry it took me so long but I've put some of my code my custom AppPoolConfigProvider on my skydrive you can access it here Or here is a gist repo to access it.

To use this provider, should place your compiled dll under an Extensibility folder (you have to create it yourself under "c:\Program Files (x86)\IIS\Microsoft Web Deploy V2\"). You can find more info about this online.

I use the provider in my xxx.wpp.targets file like this:

<Target Name="AddConfigAppPool" Condition="'$(RunConfigAppPool)'">
<Message Text="Adding configAppPool provider" />
<ItemGroup>
  <MsDeploySourceManifest Include="configAppPool">
    <path>@(__DefaultDeployEnvironmentSetting->'%(AppPoolName)')</path><!-- Represents the name of the AppPool, required-->
    <managedRuntimeVersion>$(DeployManagedRuntimeVersion)</managedRuntimeVersion>
    <managedPipelineMode>$(DeployManagedPipelineMode)</managedPipelineMode>
    <processModel_identityType>@(__DefaultDeployEnvironmentSetting->'%(AppPoolIdentyType)')</processModel_identityType>
    <processModel_userName>@(__DefaultDeployEnvironmentSetting->'%(AppPoolUserName)')</processModel_userName>
    <processModel_password>@(__DefaultDeployEnvironmentSetting->'%(AppPoolUserPassword)')</processModel_password>
    <processModel_idleTimeout>00:00:00</processModel_idleTimeout>
    <AdditionalProviderSettings>managedRuntimeVersion;managedPipelineMode;processModel_identityType;processModel_userName;processModel_password;processModel_idleTimeout</AdditionalProviderSettings>
    <!--Possible additional provider settings: queueLength,autoStart,enable32BitAppOnWin64,managedRuntimeVersion,managedRuntimeLoader,enableConfigurationOverride,managedPipelineMode,CLRConfigFile,passAnonymousToken,startMode,processModel_identityType,processModel_userName,processModel_password,processModel_loadUserProfile,processModel_logonType,processModel_manualGroupMembership,processModel_idleTimeout,processModel_maxProcesses,processModel_shutdownTimeLimit,processModel_startupTimeLimit,processModel_pingingEnabled,processModel_pingInterval,processModel_pingResponseTime,recycling_disallowOverlappingRotation,recycling_disallowRotationOnConfigChange,recycling_logEventOnRecycle,recycling_periodicRestart_memory,recycling_periodicRestart_privateMemory,recycling_periodicRestart_requests,recycling_periodicRestart_time,recycling_periodicRestart_schedule_[value='timespan']_value,failure_loadBalancerCapabilities,failure_orphanWorkerProcess,failure_orphanActionExe,failure_orphanActionParams,failure_rapidFailProtection,failure_rapidFailProtectionInterval,failure_rapidFailProtectionMaxCrashes,failure_autoShutdownExe,failure_autoShutdownParams,cpu_limit,cpu_action,cpu_resetInterval,cpu_smpAffinitized,cpu_smpProcessorAffinityMask,cpu_smpProcessorAffinityMask2-->      
  </MsDeploySourceManifest>    
</ItemGroup>

I'm sorry I can't eleborate more on this, but it's been a while since I wrote this code and I simply do not have the time. You can find some info online about creating custom providers. If you have additional questions, I'll try to answer when I have time available.

Hope this helps