我正在尝试在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,而无需手动识别目标主机上的物理路径和应用程序池用户?
答案 0 :(得分:19)
好的,首先我要说这比应该的更难!
我认为失败的原因是因为在发布时无法将该文件夹识别为IIS应用程序中的文件夹。发生这种情况的原因是,在调用SetAcl提供程序时,正在将完整路径传输到目标。而不是我们需要一个相对于IIS应用程序的路径。例如,在您的情况下,它应该类似于:“REST SERVICES / 1.0.334 / doc / public”。执行此操作的唯一方法是创建一个MSDeploy参数,该参数在发布时填充正确的值。除了在源清单中创建自己的SetAcl条目之外,您还必须执行此操作。请按照以下步骤操作。
<强> {项目名} .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中指定子目录块的好处。