ItemGroup 中的文件未被 AfterBuild Target 检测到。

6

本应该提出的问题:

这是我的ModuleCompilation.targets文件内容:

<ItemGroup>
    <ConfigFilesToMove Include="bin\$(Configuration)\*.config"/>
</ItemGroup>
<Target Name="AfterBuild">
    <Message Text="Message for AfterBuild" />
    <Move SourceFiles="@(ConfigFilesToMove)" DestinationFolder="bin\$(Configuration)\Configuration\" />
</Target>

消息已写入控制台,但文件没有被移动,为什么?

原问题(您可以忽略):

我在我的 csproj 文件中包含了一个导入来自其他文件的任务:

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\ModuleCompilation.targets" />

现在,这是我的ModuleCompilation.targets文件的内容:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="AfterBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <BaseFiles Include="bin\$(Configuration)\Libraries\ModuleBase*"/>
        <ConfigFilesToMove Include="bin\$(Configuration)\*.config"/>
        <OtherFilesToMove Include="bin\$(Configuration)\*" Exclude="bin\$(Configuration)\$(MSBuildProjectName)*" />
    </ItemGroup>
    <Target Name="AfterBuild">
        <Message Text="AfterBuild" />
        <Move SourceFiles="@(ConfigFilesToMove)" DestinationFolder="bin\$(Configuration)\Configuration\" />
        <Move SourceFiles="@(OtherFilesToMove)" DestinationFolder="bin\$(Configuration)\Libraries\" />
        <Message Text="bin\$(Configuration)\Libraries\ModuleBase*" />
        <Delete Files="@(BaseFiles)" />
    </Target>
</Project>

当我构建或重新构建时,在控制台中会出现“AfterBuild”消息,并且文件确实已生成,但它们没有从Debug文件夹移动到我想要它们的位置。
如果我重新构建我的项目,那么文件将被移动,我想这是因为它们已经存在,但我希望文件被生成然后再移动,我不希望它们已经存在!
我一定漏掉了一些非常明显的东西,请你帮帮我好吗?
编辑:
好的,所以我进行了一些测试,这个方案可行:
<ConfigFilesToMove Include="bin\Debug\App.config"/>

虽然这并不会:
<ConfigFilesToMove Include="bin\Debug\*.config"/>

有人知道为什么吗?

编辑2:

这真的很奇怪,这是我的代码:

<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <Files Include="$(OutputPath)*.config"/>

        <Pouet Include="bin\Debug\*.dll"/>
      </ItemGroup>

      <Target Name="AfterBuild">
            <Message Text="@(Pouet)" />
            <Message Text="pouetss" Condition="Exists(@(Pouet))"/>
            <Message Text="nooo" Condition="!Exists(@(Pouet))"/>
            <MakeDir Directories="$(OutputPath)Configuration\" />
            <Copy SourceFiles="@(Pouet)" DestinationFolder="$(OutputPath)Configuration\" />
  </Target>
</Project>

这是来自MSBuild日志的内容:

1>Target "AfterBuild: (TargetId:75)" in file "C:\Tests\ModuleTest\Modules\ModuleCompilation.targets" from project         "C:\Tests\ModuleTest\Modules\FirstModule\FirstModule.csproj" (target "Build" depends on it):
1>Task "Message" (TaskId:47)
1>Done executing task "Message". (TaskId:47)
1>Task "Message" skipped, due to false condition; (Exists(@(Pouet))) was evaluated as (Exists()).
1>Task "Message" (TaskId:48)
1>  Task Parameter:Text=nooo (TaskId:48)
1>  nooo (TaskId:48)
1>Done executing task "Message". (TaskId:48)
1>Task "MakeDir" (TaskId:49)
1>  Task Parameter:Directories=bin\Debug\Configuration\ (TaskId:49)
1>  Creating directory "bin\Debug\Configuration\". (TaskId:49)
1>Done executing task "MakeDir". (TaskId:49)
1>Task "Copy" (TaskId:50)
1>  Task Parameter:DestinationFolder=bin\Debug\Configuration\ (TaskId:50)
1>Done executing task "Copy". (TaskId:50)
1>Done building target "AfterBuild" in project "FirstModule.csproj".: (TargetId:75)

那么,MSBuild会忽略包含通配符的每个值吗?

2
可能是由于评估顺序的原因;您是否尝试将ItemGroup放在目标内部,以便在目标运行时(并且文件已经存在时)进行评估? - stijn
感谢您的回答@stijn。由于您的评论,我找到了这个链接:http://blogs.msdn.com/b/msbuild/archive/2005/10/04/476725.aspx,其中提到我应该在Target内使用CreateItem任务,因为在Target运行之前,Target外的项目组已经被解析。此外,MSDN表示CreateItem任务已被弃用,应该将项目组放置在Target元素中(https://msdn.microsoft.com/en-us/library/s2y3e43x),所以我想您是正确的。我会尽快更新我的帖子,一旦我有机会尝试我们的理论。 - Apollidore
1个回答

7

问题:

在 Target 之外创建的 ItemGroup 在运行任何 Target 之前解析,因此您无法定位一个 Target 将要创建的文件。

解决方案:

我将我的代码更改为:

<Target Name="AfterBuild">
    <ItemGroup>
        <ConfigFilesToMove Include="bin\$(Configuration)\*.config"/>
    </ItemGroup>
    <Message Text="Message for AfterBuild" />
    <Move SourceFiles="@(ConfigFilesToMove)" DestinationFolder="bin\$(Configuration)\Configuration\" />
</Target>

现在我的文件已被检测到,因为ItemGroup是在创建文件之后解析的。


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