如何创建在 2 个特定文件夹下的任何文件发生更改时运行的 MSBuild 目标

问题描述 投票:0回答:1

背景

我有两个输入文件夹 - A 和 B。

我有一个输出文件夹 - C.

有一个目标从 A 和 B 获取文件,并根据目录 C 中的输入创建一组文件。C 中的文件数量与 A 和 B 中的任何内容之间没有任何关系。

我想要什么?

每当这些文件夹 A 和 B 中的任何文件发生更改时,我都想运行特定的目标。

换句话说,当C与A和B不同步时,我需要运行目标。 否则,我不必运行目标。

看起来很简单吧?

我尝试了来自不同来源的多种建议,但无法得到正确的结果。

.net msbuild csproj
1个回答
0
投票

请参阅文档“增量构建”。

根据问题中的描述:当文件夹 A 或文件夹 B 有新的或更改的文件时,需要运行一个过程来创建或重新生成文件夹 C 中的输出集。文件夹 A 和 B 中的文件不会映射到文件位于文件夹 C 中。

当文件之间没有可映射关系时,可以创建哨兵文件。当目标运行并用作“输出”时,将创建或编辑哨兵文件。当输入文件比哨兵文件新时,需要运行目标。

示例:

Touch

请注意,
<Project> <PropertyGroup> <SentinelFileName>lastrun.txt</SentinelFileName> <SentinelFilePath>C</SentinelFilePath> <SentinelFile>$([System.IO.Path]::Combine($(SentinelFilePath), $(SentinelFileName)))</SentinelFile> </PropertyGroup> <Target Name="SentinelExample" Inputs="@(SrcFiles)" Outputs="C\$(SentinelFileName)" DependsOnTargets="DefineSrcFiles" > <Message Text="performing SentinelExample target" /> <MakeDir Directories="$(SentinelFilePath)" /> <Touch Files="$(SentinelFile)" AlwaysCreate="true" /> </Target> <Target Name="DefineSrcFiles"> <ItemGroup> <SrcFiles Remove="**\*.*" /> <SrcFiles Include="A\*.*" /> <SrcFiles Include="B\*.*" /> </ItemGroup> </Target> </Project>

ItemGroup 的定义会延迟到

SrcFiles
目标运行。如果有其他目标更改文件夹 A 和 B 的内容,这一点很重要。
查看示例工作:

使用示例代码创建一个文件。 (我将我的文件命名为sentinel.proj。)
  1. 创建文件夹A和B,并在文件夹中创建一些文件。
  2. 运行示例代码,例如
  3. DefineSrcFiles
  4. 应显示消息 
      msbuild sentinel.proj
    • ,应创建文件夹 C,并应创建文件
      performing SentinelExample target
      
      
    再次运行示例代码。
  5. 应显示消息
      lastrun.txt
    • 
      
    在文件夹 A 或 B 中添加或更改文件,然后再次运行示例代码。
  6. 应显示消息
      Skipping target "SentinelExample" because all output files are up-to-date with respect to the input files.
    • ,并且
      performing SentinelExample target
      文件的时间戳应更改。
      
      
  7. 删除
lastrun.txt

文件将导致目标运行。

文件夹 A 或 B 中的文件删除不会导致目标运行。这是 

lastrun.txt

Inputs
属性的限制。
    

© www.soinside.com 2019 - 2024. All rights reserved.