0

我正在尝试将一些简单的 MSBuild 任务添加到 Visual Studio 项目(VS 2012 Express)中 - 具体来说,创建一个子目录,然后将一些文件复制到输出目录的子目录中,以便打包。

我看到 VS 支持自定义构建步骤,它们是命令行调用。但是,由于 VS 基于 MSBuild,因此应该可以将这些直接添加为MSBuild 任务,例如AfterBuild 预定义目标的 Copy Task

我找不到在 Visual Studio 框架内实际添加此类任务的任何方法。该文档仅从 MSBuild 的角度讨论它,而不是它在 Visual Studio 的 UI中的工作方式。它似乎也没有讨论那里引用构建输出等的属性;大概它们只是 msbuild its self 使用的那些

Visual Studio 的 UI 中是否支持 MSBuild 任务管理,而它只是从我的 Express 版中删除了?还是我必须破解项目文件 XML 才能添加 MSBuild 任务?这是否受支持以及应该以何种方式完成?

我习惯使用 Eclipse 和 Ant 或 Maven,IDE 支持所有这些,当然您可以直接破解 XML。在 Visual Studio 中根本找不到用于 MSBuild 任务管理的 UI,这非常令人困惑。使用免费赠品版我是否错过了明显的或残废的?

4

3 回答 3

2

对于 C++ 项目,您可以使用该属性

<CppCleanDependsOn>DeleteOutputs;$(CppCleanDependsOn)</CppCleanDependsOn>

而不是像您那样定义 BeforeClean 目标。

根据我的阅读,应避免使用 CallTarget。在您的示例中,您应该使用 DependsOnTargets 来执行此操作,正如您在 MS 提供的文件中的许多虚拟目标中看到的那样。一个目标只是“调用”其他目标的函数的类似机制是通过 DependsOnTargets 完成的。流程与过程编程并不完全相同。

Intellisense:我从不使用它。仅适用于道具文件中的条件 AdditionalIncludeDirectories 是否如此?如果您在 IDE 中编辑属性并仅选择了一种配置,请继续编辑 IDE 放置它的 proj 文件中的条目。

于 2014-09-18T03:31:50.713 回答
0

我正在使用 VS2010 Pro,它没有公开 AfterBuild 目标,至少在我正在做的 C++ 项目中。如您所见,它确实具有“事件”,根据我所阅读的内容,它是为了向后兼容来自 VSBuild 的转换项目。我同意,一个 MSBuild 任务而不是一个命令脚本是要走的路。

忘记用户界面。它旨在支持 XML 文件的自由编辑,并继续使用 UI,因为它尊重您在其中的内容,并为自己的内容使用标签,以便它可以找到它来更新它。

但为了保持整洁,您可以使用属性页;一个带有 *.props 名称的独立 XML 文件,并将您想要的内容放入其中。然后使用 UI 将该道具文件添加到项目中。您不会手动编辑 UI 维护的项目文件,也不会触及 props 文件,除非您通过属性管理器视图并显式打开它。

哦,我还记得看到其他标准目标,例如打包和发布。也许这些没有用于您的项目类型,但无论如何您都可以使用这些入口点。

于 2014-09-17T06:23:14.797 回答
0

(经过大量阅读后,我发现了这是如何工作的)

Visual Studio 似乎没有公开高级 MSBuild 项目编辑,即使现代vcxproj文件只是 MSBuild 项目文件,具有一堆额外的标记属性和 Visual Studio IDE 细节的其他条目。所以你必须破解项目 XML。

vcxproj为了使其更简洁,只需在您的实际文件中添加一行- 包含一个.targets包含其余构建自定义的文件。例如,就在项目文件结束之前,插入:

  <Import Project="pg_sysdatetime.targets" />
</Build>

现在创建.targets与任何其他 MSBuild 项目具有相同结构的文件。这是我一直在从事的项目中的内容

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- MSBuild extension targets for Visual Studio build -->
  <PropertyGroup>
    <DistDir>pg_sysdatetime_pg$(PGMAJORVERSION)-$(Configuration)-$(Platform)</DistDir>
  </PropertyGroup>
  <ItemGroup>
    <DocFiles Include="README.md;LICENSE"/>
    <ExtensionSourceFiles Include="pg_sysdatetime--1.0.sql;pg_sysdatetime.control"/>
    <ExtensionDll Include="$(TargetDir)\pg_sysdatetime.dll"/>
  </ItemGroup>
  <Target Name="CopyOutputs">
    <Message Text="Copying build product to $(DistDir)" Importance="high" />
    <Copy
      SourceFiles="@(DocFiles)"
      DestinationFolder="$(DistDir)"
      />
    <Copy
      SourceFiles="@(ExtensionDll)"
      DestinationFolder="$(DistDir)\lib"
      />
    <Copy
      SourceFiles="@(ExtensionSourceFiles)"
      DestinationFolder="$(DistDir)\share\extension"
      />
  </Target>
  <Target Name="DeleteOutputs">
    <Message Text="Deleting $(DistDir)" Importance="normal" />
    <Delete Files="$(DistDir)"/>
  </Target>
  <!-- Attach to Visual Studio build hooks -->
  <Target Name="BeforeClean">
    <CallTarget Targets="DeleteOutputs"/>
  </Target>
  <Target Name="AfterBuild">
    <CallTarget Targets="CopyOutputs"/>
  </Target>
</Project>

这可以包含您想要的任何 MSBuild 任务,并分组到目标中。它还可以具有属性组、项组以及 MSBuild 支持的任何其他内容。

要集成到 Visual Studio 中,您需要添加特殊命名的目标来调用您想要的内容。在这里你可以看到我已经定义了BeforeCleanAfterBuild目标。您可以从VS 集成文档中获取支持的目标。

现在,当我构建或重建时,会自动创建一个包含产品 DLL 和一堆静态文件的新目录,并准备好压缩。如果我愿意,我可以为 MSBuild 社区扩展添加 Nuget 包,并在最后使用 Zip 任务将整个内容捆绑到一个 zip 文件中。

顺便说一句,虽然您可以在.targets文件中定义属性,但最好在属性表中定义它们。这样它们就可以在 UI 中看到。

于 2014-09-17T08:23:48.227 回答