如何使用msbuild检查项目列表中是否存在任何文件?

8

如果项目列表中有任何文件缺失,我希望能运行一个任务。该怎么做?

我的当前脚本有一个“源”文件列表 @(MyComFiles),我使用以下任务将其翻译为另一个“目标”文件列表 @(MyInteropLibs):

<CombinePath BasePath="$(MyPath)\interop" 
             Paths="@(MyComFiles->'%(filename).%(extension)')">
    <Output TaskParameter="CombinedPaths" 
            ItemName="MyInteropLibs" />
</CombinePath>

我希望检查@(MyInteropLibs)中是否有任何文件丢失,并运行任务以创建它们。

3个回答

6

如果您只需要创建缺失的文件,而不是获取缺失文件的列表,您可以使用touch任务,该任务会在文件不存在时进行创建。

<Touch Files="@(MyInteropLibs)" AlwaysCreate="True" />

如果您只想创建缺失的文件,而避免更改现有文件的时间戳,则批处理可以帮助实现此目的。

<Touch Files="%(MyInteropLibs.FullPath)" AlwaysCreate="True" 
       Condition=" ! Exists(%(MyInteropLibs.FullPath)) "/>

如果您想要一个文件创建列表,则:
<Touch Files="%(MyInteropLibs.FullPath)" AlwaysCreate="True" 
       Condition=" ! Exists(%(MyInteropLibs.FullPath)) ">
    <Output TaskParameter="TouchedFiles" ItemName="CreatedFiles"/>
</Touch>
<Message Text="Created files = @(CreatedFiles)"/>

3

我对MSBuild并不是很有经验,所以可能有比这更好的解决方案,但你可以编写一个FilesExist任务,将文件列表传递给它,并将每个文件传递给File.Exists,如果它们存在则返回true,否则返回false,然后根据结果进行反应。

抱歉,我不能提供代码来帮助解决问题,我的MSBuild语法知识不够强。


我宁愿在msbuild中完成。可以在任务的条件属性中使用Exists()函数,但它只适用于一个文件。 - Magnus Lindhe
2
看起来MSBuild没有内置此功能。在MSBuild Extension Pack或MSBuild Community Tasks中也没有看到这样的功能。正如Crippledsmurf建议的那样,您可以创建自己的自定义MSBuild任务来完成所需的操作。然后,在构建文件中引用dll并根据需要调用该任务。 - Pedro

1
你可以通过使用Exec轻松找出答案。
要测试一组文件是否全部存在:DOS FOR /D命令接受一个以分号分隔的文件列表 - 即一个扁平的项目数组。
<!-- All exist -->
<Exec
  Command="for /D %%i in (@(MyFiles)) do if not exist %%i exit 1"
  IgnoreExitCode="true">
  <Output TaskParameter="ExitCode" PropertyName="ExistExitCode"/>
</Exec>

为了测试一组文件中是否存在任何一个:DOS DIR命令接受由分号分隔的文件列表。如果在列表中找到任何文件,则将%ERRORLEVEL%设置为0,如果未找到,则设置为非零值。(这是更简单的情况,但它并没有解决原始问题...)
<!-- Any exists -->
<Exec Command="dir /B @(MyFiles)" IgnoreExitCode="true">
  <Output TaskParameter="ExitCode" PropertyName="DirExitCode"/>
</Exec>

如果您想基于输出定义一个布尔属性,那么最有可能需要这样做。

编辑: 顺便提一下,这是一种代码异味。通常当您发现自己想要这样做时,这表明您应该设置目标的“Outputs”属性,以便它将循环遍历项目。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接