Web Deploy的setAcl提供程序可以在子目录中使用吗?

时间:2011-07-28 15:59:06

标签: visual-studio-2010 iis-7 msdeploy webdeploy

我正在尝试在MS Deploy包中创建一个可写入应用程序池用户的子目录。感谢Kevin Leetham的helpful post about the setAcl provider,我能够将我需要的大部分内容放到我的项目文件中:

<MsDeploySourceManifest Include="setAcl"
                        Condition="$(IncludeSetAclProviderOnDestination)">
  <Path>$(_MSDeployDirPath_FullPath)\doc\public</Path>
  <setAclAccess>Read,Write,Modify</setAclAccess>
  <setAclResourceType>Directory</setAclResourceType>
  <AdditionalProviderSettings>setAclResourceType;setAclAccess</AdditionalProviderSettings>
</MsDeploySourceManifest>

请注意,我已将“\ doc \ public”添加到根部署目录。在VS2010构建的结果清单中,我看到以下setAcl元素:

<sitemanifest>
  <contentPath path="C:\Source\...\obj\Debug\Package\PackageTmp" />
  <setAcl path="C:\Source\...\obj\Debug\Package\PackageTmp"
          setAclResourceType="Directory" />
  <setAcl path="C:\Source\...\obj\Debug\Package\PackageTmp"
          setAclUser="anonymousAuthenticationUser"
          setAclResourceType="Directory" />
  <setAcl path="C:\Source\...\obj\Debug\Package\PackageTmp\doc\public"
          setAclResourceType="Directory"
          setAclAccess="Read,Write,Modify" />
</sitemanifest>

最后一行看起来不错:它附加了我想要写的子目录,并且访问修饰符似乎都转移得很好。

但是,当我部署此程序包时,我收到错误:

  

错误:必须在指定'setAclUser'设置的值时指定   'setAcl'提供程序与物理路径一起使用。

这是一个令人困惑的错误,因为我并没有尝试在物理路径上设置ACL,而是在Web应用程序的子目录中。查看MS Deploy的输出,很容易看出问题所在:

Info: Adding setAcl (REST Services\1.0.334).
Info: Adding setAcl (REST Services\1.0.334).
Info: Adding setAcl (C:\...\obj\Release\Package\PackageTmp\doc\public).

MS Deploy显然用我的绝对路径“C:... \ obj \ Release \ Package \ PackageTmp”替换了Web应用程序名称,但当我将“\ doc \ public”附加到该绝对路径时,它不再识别它作为Web应用程序目录。这个确切的问题由另一个受害者over on the ASP.NET forums描述,没有任何解决方案。

有没有人知道如何通过Web Deploy在Web应用程序的特定子目录上设置ACL,而无需手动识别目标主机上的物理路径和应用程序池用户?

2 个答案:

答案 0 :(得分:19)

好的,首先我要说这比应该的更难!

我认为失败的原因是因为在发布时无法将该文件夹识别为IIS应用程序中的文件夹。发生这种情况的原因是,在调用SetAcl提供程序时,正在将完整路径传输到目标。而不是我们需要一个相对于IIS应用程序的路径。例如,在您的情况下,它应该类似于:“REST SERVICES / 1.0.334 / doc / public”。执行此操作的唯一方法是创建一个MSDeploy参数,该参数在发布时填充正确的值。除了在源清单中创建自己的SetAcl条目之外,您还必须执行此操作。请按照以下步骤操作。

  1. 在与项目相同的目录中创建名为{ProjectName} .wpp.targets的文件(其中{ProjectName}是Web应用程序项目的名称)
  2. 在文件内部粘贴此列表下方的MSBuild内容
  3. 在Visual Studio中重新加载项目(VS将项目文件缓存在内存中,因此需要清除此缓存)。
  4. <强> {项目名} .wpp.targets

    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    
      <Target Name="SetupCustomAcls" AfterTargets="AddIisSettingAndFileContentsToSourceManifest">   
        <!-- This must be declared inside of a target because the property 
        $(_MSDeployDirPath_FullPath) will not be defined at that time. -->
        <ItemGroup>
          <MsDeploySourceManifest Include="setAcl">
            <Path>$(_MSDeployDirPath_FullPath)\doc\public</Path>
            <setAclAccess>Read,Write,Modify</setAclAccess>
            <setAclResourceType>Directory</setAclResourceType>
            <AdditionalProviderSettings>setAclResourceType;setAclAccess</AdditionalProviderSettings>
          </MsDeploySourceManifest>
        </ItemGroup>
      </Target>
    
      <Target Name="DeclareCustomParameters" AfterTargets="AddIisAndContentDeclareParametersItems">
        <!-- This must be declared inside of a target because the property 
        $(_EscapeRegEx_MSDeployDirPath) will not be defined at that time. -->
        <ItemGroup>
          <MsDeployDeclareParameters Include="DocPublicSetAclParam">
            <Kind>ProviderPath</Kind>
            <Scope>setAcl</Scope>
            <Match>^$(_EscapeRegEx_MSDeployDirPath)\\doc\\public$</Match>
            <Value>$(_DestinationContentPath)/doc/public</Value>
            <ExcludeFromSetParameter>True</ExcludeFromSetParameter>
          </MsDeployDeclareParameters>
        </ItemGroup>
      </Target>
    
    </Project>
    

    为了解释这一点,目标SetupCustomAcls将使新的SetAcl条目放在发布期间使用的源清单中。通过AfterTargets属性执行 AddIisSettingAndFileContentsToSourceManifest 目标后执行此目标。我们这样做是为了确保在正确的时间创建项值,因为我们需要确保填充 _MSDeployDirPath_FullPath 属性。

    DeclareCustomParameters是创建自定义MSDeploy参数的位置。该目标将在 AddIisAndContentDeclareParametersItems 目标之后执行。我们这样做是为了确保填充 _EscapeRegEx_MSDeployDirPath 属性。当我声明参数的值(在Value元素内)我使用属性 _DestinationContentPath 时,请注意该目标内部,该属性是包含应用程序部署路径的MSBuild属性,即 REST服务/ 1.0.334

    你可以尝试一下,让我知道它是否适合你?

答案 1 :(得分:3)

仅供参考 - 如果您遵循此处帖子中指定的惯例,这对根网站有效: http://forums.iis.net/p/1176955/1977169.aspx#1977169

<Match>^$(_EscapeRegEx_MSDeployDirPath)\\@(CustomDirAcl)$</Match>
<DefaultValue>{$(_MsDeployParameterNameForContentPath)}/@(CustomDirAcl)</DefaultValue>
<Value>$(_DestinationContentPath)/@(CustomDirAcl)</Value>

此帖子还具有能够在单个ItemGroup中指定子目录块的好处。