Note: I’d like to thank Tom Dykstra for helping me put this together
As part of the deployment process you might need to set permissions on one or more folders in the destination web application. For example, if your application allows users to upload files, it needs write access to a folder in order to store the uploaded files. By default, theweb publishing pipeline (the automated deployment process) automatically sets write permission on the App_Data folder in order to enable database updates in case you store databases in that folder, and you can use the same method to make the deployment process automatically set permissions on any folder you choose.
The .wpp.targets File
The web publishing pipeline is controlled by MSBuild .targets files that are installed with Visual Studio. Rather than editing the Visual Studio .targets files, you can create a project-specific .targets file that Visual Studio will use to modify the deployment process for a specific project. To do that, you create an XML file in the project folder and name it < projectname>.wpp.targets. The following example shows XML markup that causes the web publishing pipeline to set write permissions for a folder named Elmah located in the root folder of the application. The sample is designed to work for both deployment methods: publish or web deployment package.
$(_MSDeployDirPath_FullPath)\Elmah Read,Write Directory setAclResourceType;setAclAccess ProviderPath setAcl ^$(_EscapeRegEx_MSDeployDirPath)\\Elmah$ Add write permission to the Elmah folder. {$(_MsDeployParameterNameForContentPath)}/Elmah $(_DestinationContentPath)/Elmah Hidden $(VsSetAclPriority) True
The first Target
element ("SetupCustomAcls") causes a setAcl
action to be added to the deployment package's source manifest when the package is created. The source manifest is a file that specifies what to include in the deployment package. The path to the folder is specified using an MSBuild variable (_MSDeployDirPath_FullPath
) that specifies the path to the project root folder:
This isn't all you need to do, however, because the permissions actually need to be set on the folder in the destination application, not the folder in the deployment package. That's why the second Target
element is needed. The second Target
element ("DeclareCustomParameters") creates a user-defined Web Deploy parameter named ElmahSetAclParam
. The value of this parameter will change the value of the setAcl
path at deploy time. TheDefaultValue
element of the ElmahSetAclParam
parameter sets the value that will be used when you are deploying by creating and installing a deployment package; the Value
element sets the value that will be used when you are publishing without using a deployment package.
If you are using a deployment package, the actual path to the destination folder isn't known until the package is installed. Therefore the default value of this parameter is set using an MSDeploy parameter that resolves to the name of a system-defined Web Deploy parameter:
{$(_MsDeployParameterNameForContentPath)}/Elmah
When the package is created, _MsDeployParameterNameForContentPath
is translated into "{IIS Web Application Name}", so the actual default value becomes "{IIS Web Application Name}/Elmah". When the package is installed, the value of that Web Deploy parameter is the path of the destination root folder, and so as a result the ElmahSetAclParam
parameter resolves to the physical path of the destination Elmah folder (for example: C:\inetpub\wwwroot\ContosoUniversity\Elmah). That path then replaces the package's physical path for the Elmah setAcl
element in the source manifest.
When you publish the project rather than using a deployment package, the Value
element instead of the DefaultValue
element provides the value for the ElmahSetAclParam
parameter. In that case, you are deploying from Visual Studio, and Visual Studio has the actual destination path value in an MSBuild property, so the Value
element can specify that MSBuild property directly and does not need to use a Web Deploy variable:
$(_DestinationContentPath)/Elmah
The "Hidden" value in the Tags
element prevents the ElmahSetAclParam
parameter from being displayed in the IIS Manager UI if you use IIS Manager to install the package. The UI doesn't have to show the value, because a user never needs to change it manually.
Hidden
Adding More Folders
You can add more folders by adding ItemGroup
elements. The following example builds on the earlier one by also granting Read permission for the bin folder to the NETWORK SERVICE account. (This is required in some cases for SQL Server Compact.) Notice that in order to specify the account to which access is granted, "setAclUser" was added to the < AdditionalProviderSettings>
element, and a
element specifying NETWORK SERVICE was added.
$(_MSDeployDirPath_FullPath)\Elmah Read,Write Directory setAclResourceType;setAclAccess $(_MSDeployDirPath_FullPath)\bin NETWORK SERVICE Read Directory setAclUser;setAclResourceType;setAclAccess ProviderPath setAcl ^$(_EscapeRegEx_MSDeployDirPath)\\Elmah$ Add write permission to the Elmah folder. {$(_MsDeployParameterNameForContentPath)}/Elmah $(_DestinationContentPath)/Elmah Hidden $(VsSetAclPriority) True ProviderPath setAcl ^$(_EscapeRegEx_MSDeployDirPath)\\Bin$ Add read permission to the bin folder. {$(_MsDeployParameterNameForContentPath)}/bin $(_DestinationContentPath)/bin Hidden $(VsSetAclPriority) True
.targets File Caching in Visual Studio
Setting up .targets files is like writing code -- rarely do you get everything right the first time. If you do make a mistake that you have to fix, you should be aware that Visual Studio caches target files. This means that every time you change a .targets file, you must exit Visual Studio and restart it before you rebuild the package in order to see the effect of your change. This is not an issue if you create packages using the command line.
Making Changes that Affect Parameters in Packages
Visual Studio will not rebuild a package if it cannot determine that a change has been made, and changes that affect Web Deploy parameters are sometimes not recognized as changes. Therefore, if you make any changes that affect parameters in the source manifest, it's best to select Clean Solution from the Build menu in order to delete the contents of the Package folder before you rebuild the package.
Sayed Ibrahim Hashimi – @SayedIHashimi
Comments are closed.