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


Comment Section



Comments are closed.