选择要生成的文件

在大多数项目中,无需特别选择要生成的文件。 例如,使用 Visual Studio 创建的任何项目都会生成项目中的所有源文件。 但是,可能需要了解如何编辑项目文件来处理不同于默认场景的场景,例如,如果要从项目文件夹之外的其他位置生成文件,或者创建自己的生成过程而不是使用 .NET SDK 等 SDK。

不同项目类型的默认行为

决定 MSBuild 在生成中要包含的文件的默认行为因项目类型而异。

对于 .NET SDK 项目,标准 .NET SDK 会定义一个默认的 Compile 项列表,其中包含项目文件夹树中与相关特定语言的文件扩展名匹配的文件。 例如,对于 C# 项目, Compile 项使用 glob 模式 **/*.cs 填充,该模式与项目文件夹中的所有源文件及其所有子文件夹以递归方式匹配。 你不会看到项目文件中的 Compile 元素,因为它是在隐式导入的 SDK .props 文件中定义的。 请参阅 .NET 项目 SDK 概述 - 默认包含和排除的内容

如果使用的是 Visual Studio,则可以通过更改文件上的“生成操作”来修改要生成的源文件集。 将它设置为 None,以在生成时排除文件。 在 Visual Studio 中执行此操作会影响项目文件。 你将看到已添加了相关行,以从 Compile 项列表中移除源文件,并将其添加到 None 项列表中。

  <ItemGroup>
    <Compile Remove="Class.cs" />
  </ItemGroup>

  <ItemGroup>
    <None Include="Class.cs" />
  </ItemGroup>

对于 .NET Framework 或其他非 SDK 项目,Compile 项通过列出所有源文件的方式在项目文件中显式构造。

对于 C++项目,源文件将显式添加到项目文件中的 ClCompile 元素。

如果在不使用 SDK 的情况下手动编写 MSBuild 项目文件,则可以在项目文件中分别列出每个源文件,也可以使用通配符将一个目录或一组嵌套目录中的所有文件都包含在内。 还可以使用本文中的方法来修改 Compile 项列表(对于 .NET 项目)或 ClCompile 项列表(对于 C++项目),以自定义要生成的文件。

指定输入

项表示某个生成的输入(例如源文件)。 有关项的详细信息,请参阅

要包括某个生成的文件,则必须将其包含在项列表中。 如前讨论,在 .NET SDK 和 .NET Framework 项目中,源文件的项列表为 Compile。 对于 .NET SDK 项目,你不会看到 Compile 项列表,因为它是在隐式导入中定义的。 请参阅使用项目 SDK

不依赖于标准导入的项目文件可以使用任意项列表名称,例如 VBFileCSFile。 请参阅本文后面的示例 1示例 2。 要设置基于项列表的生成,请按名称将此传递给生成任务,如本文后面部分所讨论。

通过逐个包括文件或使用通配符同时包括许多文件,可以将多个文件添加到项列表中。

逐个声明各个项

  • 使用 Include 属性,如下所示:

    <Compile Include="Form1.cs"/>

    <Compile Include="Form1.vb"/>

    注意

    如果项集合中的项不在项目文件所在的同一目录中,则必须指定项的完整路径或相对路径。 例如:Include="..\..\Form2.cs"

同一项列表可以按多个 Include 属性重复修改。 每个 Include 都会都添加到之前的内容。

声明多个项

  • 使用 Include 属性,如下所示:

    <Compile Include="Form1.cs;Form2.cs"/>

    <Compile Include="Form1.vb;Form2.vb"/>

使用通配符指定输入

还可以使用通配符以递归方式将子目录中的所有文件或某些特定文件包括在某个生成的输入中。 有关通配符的详细信息,请参阅通配符

下面的示例基于一个项目,该项目包含下列目录和子目录中的图形文件,项目文件位于 Project 目录中:

Project\Images\BestJpgs

Project\Images\ImgJpgs

Project\Images\ImgJpgs\Img1

包括 Images 目录和子目录中的所有 .jpg 文件

  • 使用下面的 Include 属性:

    Include="Images\**\*.jpg"

包括所有以“img”开头的 .jpg 文件

  • 使用下面的 Include 属性:

    Include="Images\**\img*.jpg"

包括目录中名称以“jpgs”结尾的所有文件

  • 使用以下 Include 属性之一:

    Include="Images\**\*jpgs\*.*"

    Include="Images\**\*jpgs\*"

排除和移除项

可能需要指定与特定模式匹配的文件,同时也有一些例外情况。 通过组合使用 IncludeExclude,可以通过单个操作完成此操作。

<ItemGroup>
  <!-- Include every C# source file, except anything in the "sub" folder -->
  <Compile Include="**/*.cs" Exclude="sub/**/*.cs">
</ItemGroup>

要移除以前包含的或 SDK 默认包含的项,则可以使用 Remove 属性。

<ItemGroup>
  <!-- Remove anything in the "sub" folder -->
  <Compile Remove="sub/**/*.cs">
</ItemGroup>

将项传递到任务或目标

在大多数项目文件中,无需将 Compile 项显式传递到目标或任务,因为这将由标准导入处理。 不过对于目标项目文件,可以在任务中使用 @() 表示法来将整个项列表指定为生成的输入。 无论是分别列出所有文件还是使用通配符,均可以使用此表示法。

将所有 C# 或 Visual Basic 文件作为编译器任务的输入使用

  • 使用 Include 属性,如下所示:

    <CSC Sources="@(CSFile)">...</CSC>

    <VBC Sources="@(VBFile)">...</VBC>

注意

必须将通配符与项配合使用来指定生成的输入,不能使用 MSBuild 任务(如 CscVbc)中的 Sources 属性来指定输入。 下面的示例在项目文件中无效:

<CSC Sources="*.cs">...</CSC>

示例 1

以下代码示例演示的项目单独包括所有输入文件。

<Project DefaultTargets="Compile"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
    <PropertyGroup>
        <Builtdir>built</Builtdir>
    </PropertyGroup>

    <ItemGroup>
        <CSFile Include="Form1.cs"/>
        <CSFile Include="AssemblyInfo.cs"/>

        <Reference Include="System.dll"/>
        <Reference Include="System.Data.dll"/>
        <Reference Include="System.Drawing.dll"/>
        <Reference Include="System.Windows.Forms.dll"/>
        <Reference Include="System.XML.dll"/>
    </ItemGroup>

    <Target Name="PreBuild">
        <Exec Command="if not exist $(builtdir) md $(builtdir)"/>
    </Target>

    <Target Name="Compile" DependsOnTargets="PreBuild">
        <Csc Sources="@(CSFile)"
            References="@(Reference)"
            OutputAssembly="$(builtdir)\$(MSBuildProjectName).exe"
            TargetType="exe" />
    </Target>
</Project>

示例 2

以下代码示例使用通配符来包括所有 .cs 文件。

<Project DefaultTargets="Compile"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >

    <PropertyGroup>
        <builtdir>built</builtdir>
    </PropertyGroup>

    <ItemGroup>
        <CSFile Include="*.cs"/>

        <Reference Include="System.dll"/>
        <Reference Include="System.Data.dll"/>
        <Reference Include="System.Drawing.dll"/>
        <Reference Include="System.Windows.Forms.dll"/>
        <Reference Include="System.XML.dll"/>
    </ItemGroup>

    <Target Name="PreBuild">
        <Exec Command="if not exist $(builtdir) md $(builtdir)"/>
    </Target>

    <Target Name="Compile" DependsOnTargets="PreBuild">
        <Csc Sources="@(CSFile)"
            References="@(Reference)"
            OutputAssembly="$(builtdir)\$(MSBuildProjectName).exe"
            TargetType="exe" />
    </Target>
</Project>