MSBuild:如何创建包含多个 <Exec> 任务的参数化内联任务

MSBuild: How to create parametrized inline-task containing multiple <Exec> tasks

我有以下简单的任务:

<Exec Command="  icacls   &quot;$( [System.IO.Path]::Combine( $(_tempPublishUrl), Logs              ))&quot;  /grant      Users:(CI)(OI)M  /T  "  ContinueOnError="true" />
<Exec Command="  icacls   &quot;$( [System.IO.Path]::Combine( $(_tempPublishUrl), Logs              ))&quot;  /grant  IIS_IUSRS:(CI)(OI)M  /T  "  ContinueOnError="true" />

<Exec Command="  icacls   &quot;$( [System.IO.Path]::Combine( $(_tempPublishUrl), ReportResults     ))&quot;  /grant      Users:(CI)(OI)M  /T  "  ContinueOnError="true" />
<Exec Command="  icacls   &quot;$( [System.IO.Path]::Combine( $(_tempPublishUrl), ReportResults     ))&quot;  /grant  IIS_IUSRS:(CI)(OI)M  /T  "  ContinueOnError="true" />

<Exec Command="  icacls   &quot;$( [System.IO.Path]::Combine( $(_tempPublishUrl), ReportTemplates   ))&quot;  /grant      Users:(CI)(OI)M  /T  "  ContinueOnError="true" />
<Exec Command="  icacls   &quot;$( [System.IO.Path]::Combine( $(_tempPublishUrl), ReportTemplates   ))&quot;  /grant  IIS_IUSRS:(CI)(OI)M  /T  "  ContinueOnError="true" />

我想创建一个可重复使用的任务,它将这些执行任务的“_tempPublishUrl”参数化,因为我想在 msbuild 脚本的不同部分重复使用它们(也就是消除代码重复)。我知道我可以像这样创建简单的 C# 任务:

<UsingTask
  TaskName="RenameDirectory"
  TaskFactory="CodeTaskFactory"
  AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll"
>
  <ParameterGroup>
    <PathToDirToRename          ParameterType="System.String"    Required="true" />
    <PathToNewDirectoryName     ParameterType="System.String"    Required="true" />
  </ParameterGroup>

  <Task>
    <Reference  Include="System.Core" />
    <Using Namespace="System" />

    <Code Type="Fragment" Language="cs">
      <![CDATA[
          System.IO.Directory.Move(PathToDirToRename, PathToNewDirectoryName);
      ]]>
    </Code>
  </Task>
</UsingTask>

但是我如何使用 对我的 任务进行分组,以便创建可重复使用的任务(思考函数)?我找不到这样的例子。

据我了解,您可以将Exec组合成带参数的Target,然后使用CallTarget

I want to create a re-usable task which parametrizes "_tempPublishUrl" of these exec-tasks because I want to re-use them in different parts of an msbuild script (aka eliminate code-duplication).

作为解决方法,您可以在 .targets/.props 文件中定义 _tempPublishUrl,例如:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <_tempPublishUrl>SomeValue1</_tempPublishUrl>
  </PropertyGroup>
</Project>

然后当您在 msbuild 脚本的不同部分重新使用它们时,您可以导入此 .targets/.props 文件:

<Import Project="..\Path\xxxx.targets" />

甚至你可以使用nuget来管理这个文件,这样我们就不需要手动导入这个.targets/.props文件,只需将nuget包添加到一个msbuild的不同部分脚本,查看 Creating native packages 了解更多详情。

此外,您还可以在.targets/.props文件中添加<UsingTask>。在这种情况下,我们不需要重复 <UsingTask> 代码,我们可以在导入 .targets/.props 文件或安装 nuget 包后重新使用它。

希望对您有所帮助。

就我的研究而言,实现预期效果的唯一方法是将所需功能提取到单独的 .msbuild 文件中,并在以下情况下使用任务的 Properties="..." 属性调用上述卫星 .msbuild 文件。这种方法并不理想,因为卫星 .msbuild 仍然暴露在通过“/p”开关传递给根 .msbuild 文件的全局属性上。但它已经足够接近理想状态了,总比没有好。