在Visual Studio 2012中使用MSBuild PublishProfile时,MSDeploy跳过规则

nek*_*kno 23 msbuild msdeploy visual-studio webdeploy visual-studio-2012

我正在尝试使用WebDeploy使用自定义MSDeploy跳过规则和Visual Studio 2012中保存的发布配置文件来发布网站.

我从命令行使用发布配置文件,但跳过删除文件夹的跳过规则不起作用.

我的ErrorLog网络应用程序中有一个子文件夹,web.config里面有一个文件来设置正确的文件夹权限.没有任何跳过规则,ErrorLog文件夹和web.config文件将正常发布,但服务器上文件夹中的所有现有错误日志文件将在发布时删除.


错误 <SkipAction>Delete</SkipAction>

当我向我的wpp.targets文件添加自定义跳过规则时,跳过规则不再接受该<SkipAction>元素的值.如果我设置<SkipAction>Delete</SkipAction>,我收到以下错误:

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.targets(4377,5): error : Web deployment task failed. (Unrecognized skip directive 'skipaction'. Must be one of the following: "objectName," "keyAttribute," "absolutePath," "xPath," "attributes.<name>.") [C:\inetpub\wwwroot\My.Website\My.Website\My.Website.csproj]
Run Code Online (Sandbox Code Playgroud)

如果我只是省略该<SkipAction>元素,ErrorLog则在正常发布时删除该文件夹.

如果我<SkipAction></SkipAction>再次设置,ErrorLog则在发布时删除该文件夹.

如果我设置<KeyAttribute>Delete</KeyAttribute>,然后ErrorLogweb.config文件通常刊载.

我的理解是,为了使用自定义跳过规则,您需要从命令行调用MSBuild而不是从VS 2012中发布.但是,我仍然想使用我保存的发布配置文件,我知道现在可以使用VS 2012.


我的MSBuild命令行:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe My.Website.sln /p:Configuration=Release;DeployOnBuild=true;PublishProfile="Test Server - Web Deploy"
Run Code Online (Sandbox Code Playgroud)

My.Website.wpp.targets:

<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <AfterAddIisSettingAndFileContentsToSourceManifest>AddCustomSkipRules</AfterAddIisSettingAndFileContentsToSourceManifest>
  </PropertyGroup>

  <Target Name="AddCustomSkipRules">
    <Message Text="Adding Custom Skip Rules" />
    <ItemGroup>
      <MsDeploySkipRules Include="SkipErrorLogFolder1">
        <SkipAction></SkipAction>
        <KeyAttribute>Delete</KeyAttribute>
        <ObjectName>dirPath</ObjectName>
        <AbsolutePath>$(_Escaped_WPPAllFilesInSingleFolder)\\ErrorLog$</AbsolutePath>
        <XPath></XPath>
      </MsDeploySkipRules>
    </ItemGroup>
  </Target>
</Project>
Run Code Online (Sandbox Code Playgroud)

我的MSBuild输出显示自定义跳过规则,但仍然删除文件:

GenerateMsdeployManifestFiles:
  Generate source manifest file for Web Deploy package/publish ...
AddCustomSkipRules:
  Adding Custom Skip Rules
MSDeployPublish:
  Start Web Deploy Publish the Application/package to http://testserver.domain.com/MSDEPLOYAGENTSERVICE ...
  Starting Web deployment task from source: manifest(C:\inetpub\wwwroot\My.Website\My.Website\obj\Release\Package\My.Website.SourceManifest.xml) to Destination: auto().
  Deleting filePath (MyWeb/ErrorLog\test.txt).
  Updating setAcl (MyWeb/).
  Updating setAcl (MyWeb/).
  Updating filePath (MyWeb/ErrorLog\Web.config).
  Updating filePath (MyWeb/Web.config).
  Updating setAcl (MyWeb/).
  Updating setAcl (MyWeb/).
  Successfully executed Web deployment task.
  Publish is successfully deployed.
Run Code Online (Sandbox Code Playgroud)

Ric*_*lay 23

编辑:事实证明你是对的:从Visual Studio执行时会忽略skip指令.

幸运的是,有一个解决方法.

你想要的是这个:

<!-- Skip the deletion of any file within the ErrorLog directory -->
<MsDeploySkipRules Include="SkipErrorLogFolder1">
  <SkipAction>Delete</SkipAction>
  <ObjectName>filePath</ObjectName>
  <AbsolutePath>ErrorLog</AbsolutePath>
</MsDeploySkipRules>
Run Code Online (Sandbox Code Playgroud)

此外,您需要阻止VS使用UI任务(它似乎包含有关跳过规则的错误).您可以通过在wpp.targets或pubxml中声明以下内容来执行此操作:

<PropertyGroup>
  <UseMsDeployExe>true</UseMsDeployExe>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)

我在本地测试了这个,我可以确认它是否按预期工作:附加文件已更新,但目录中没有文件被删除.


nek*_*kno 9

作为参考,这是我的完整.wpp.targets文件,其中包含工作跳过规则,以跳过删除ErrorLog文件夹和自定义ACL以使ErrorLog文件夹在服务器上可写.

从VS 2012 Update 3开始,这仅适用于从命令行使用MSBuild发布DeployOnBuild=true;PublishProfile="Test Server - Web Deploy"传递给MSBuild 的选项.从VS内部发布时,这不起作用.

<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <UseMsdeployExe>true</UseMsdeployExe> <!-- Required for the MSDeploySkipRules to work -->
    <DeployManagedPipelineMode>Integrated</DeployManagedPipelineMode>
  </PropertyGroup>

  <PropertyGroup>
    <AfterAddIisSettingAndFileContentsToSourceManifest>
      $(AfterAddIisSettingAndFileContentsToSourceManifest);
      AddCustomSkipRules;
    </AfterAddIisSettingAndFileContentsToSourceManifest>
  </PropertyGroup>

  <Target Name="AddCustomSkipRules">
    <Message Text="Adding Custom Skip Rules" />
    <ItemGroup>
      <MsDeploySkipRules Include="SkipErrorLogFolder">
        <SkipAction>Delete</SkipAction>
        <ObjectName>filePath</ObjectName>
        <AbsolutePath>ErrorLog</AbsolutePath>
        <XPath></XPath>
      </MsDeploySkipRules>
    </ItemGroup>
  </Target>

  <PropertyGroup>
    <AfterAddIisSettingAndFileContentsToSourceManifest>
      $(AfterAddIisSettingAndFileContentsToSourceManifest);
      SetCustomACLs;
    </AfterAddIisSettingAndFileContentsToSourceManifest>
    <AfterAddDeclareParametersItemsForContentPath>
      $(AfterAddDeclareParametersItemsForContentPath);
      SetCustomAclParameters;
    </AfterAddDeclareParametersItemsForContentPath>
  </PropertyGroup>

  <Target Name="SetCustomACLs">
    <Message Text="Setting Custom ACLs" />
    <ItemGroup>
      <!--Make sure the application pool identity has write permission to the download folder--> 
      <MsDeploySourceManifest Include="setAcl"
        Condition="$(IncludeSetAclProviderOnDestination) And Exists('$(_MSDeployDirPath_FullPath)\ErrorLog')">
        <Path>$(_MSDeployDirPath_FullPath)\ErrorLog</Path>
        <setAclAccess>Write</setAclAccess>
        <setAclResourceType>Directory</setAclResourceType>
        <AdditionalProviderSettings>setAclResourceType;setAclAccess</AdditionalProviderSettings>
      </MsDeploySourceManifest>
    </ItemGroup>
  </Target>

  <Target Name="SetCustomAclParameters">
    <Message Text="Setting Custom ACL Parameters" />
    <EscapeTextForRegularExpressions Text="$(_MSDeployDirPath_FullPath)">
      <Output TaskParameter="Result" PropertyName="_EscapeRegEx_MSDeployDirPath" />
    </EscapeTextForRegularExpressions>
    <ItemGroup>
      <MsDeployDeclareParameters Include="Add write permission to ErrorLog folder"
        Condition="$(IncludeSetAclProviderOnDestination) and Exists('$(_MSDeployDirPath_FullPath)\ErrorLog')">
        <Kind>ProviderPath</Kind>
        <Scope>setAcl</Scope>
        <Match>^$(_EscapeRegEx_MSDeployDirPath)\\ErrorLog$</Match>
        <Description>Add write permission to ErrorLog folder</Description>
        <DefaultValue>Default Web Site/ErrorLog</DefaultValue>
        <Value>$(DeployIisAppPath)/ErrorLog</Value>
        <Tags>Hidden</Tags>
        <Priority>$(VsSetAclPriority)</Priority>
        <ExcludeFromSetParameter>True</ExcludeFromSetParameter>
      </MsDeployDeclareParameters>
    </ItemGroup>
  </Target>
</Project>
Run Code Online (Sandbox Code Playgroud)

  • 整个目标文件是无价的.谢谢! (2认同)