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

lad*_*dge 18 iis-7 visual-studio-2010 msdeploy webdeploy

我正在尝试在MS Deploy包中创建一个可写入应用程序池用户的子目录.感谢Kevin Leetham 关于setAcl提供程序有用帖子,我能够将我需要的大部分内容放到我的项目文件中:

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

请注意,我已将"\ 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>
Run Code Online (Sandbox Code Playgroud)

最后一行看起来很好:它附加了我想要写的子目录,并且访问修饰符似乎已经转移得足够好了.

但是,当我部署此包时,我收到一个错误:

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

这是一个令人困惑的错误,因为我并没有尝试在物理路径上设置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).
Run Code Online (Sandbox Code Playgroud)

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

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

Say*_*imi 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将项目文件缓存在内存中,因此需要清除此缓存).

{}项目名.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>
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 仅供参考 - 这似乎不适用于未被推入虚拟目录并被推送到默认站点/的应用程序.我正在试图弄清楚如何调整它,以便它也适用于那种情况.错误位于调用VSMSDeploy的Web.Publishing.targets的第3847行 - "站点"不存在. (3认同)