在Visual Studio(2010及以上版本)中查看文件属性时,可以在"常规"部分设置项目类型。例如,对于c++,项目类型是"C/c++ compiler"。
有一个"自定义构建工具"类型可用,但是它必须为该类别中的每个文件完全配置。
我的问题是:
- 是否有办法配置"自定义构建工具",并使其在项目类型列表中可用;
- 是否可以将文件扩展名与这个新的项目类型生成器关联?
我使用以下引用找到了答案:
-
Integrating a compiler/assembler in VS ; Using NASM with Visual Studio 2010
by dangerous brain on CodeProject: http://www.codeproject.com/Articles/410776/Integrating-a-compiler-assembler-in-VS-Using-NASM -
Platform Extensibility - Part 1
由Pavan Adharapurapu在MSDN博客:https://learn.microsoft.com/en-us/archive/blogs/vsproject/platform-extensibility-part-1 -
Platform Extensibility - Part 2
由Pavan Adharapurapu在MSDN博客:https://learn.microsoft.com/en-us/archive/blogs/vsproject/platform-extensibility-part-2 -
MSBuild API Reference
在MSDN: https://msdn.microsoft.com/en-us/library/dn715758(v=vs.121).aspx '
事实证明,完整的设置相当复杂,所以我将用最简单的步骤来回答我最初的两个问题:
在MSVC中添加自定义构建工具
-
在项目文件(
vcxproj
),包括一个新的构建定义(可能有一种方法,包括它的系统范围,但我还没有看到它):<ImportGroup Label="ExtensionTargets"> <Import Project="mybuild.targets" /> </ImportGroup>
可以在关闭</Project>
之前。
-
在与
vcxproj
文件相同的文件夹中创建一个名为mybuild.targets
的文本文件 -
在
mybuild.targets
中插入以下内容:<?xml version="1.0" encoding="utf-8"?> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <PropertyPageSchema Include="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml" /> </ItemGroup> </Project>
-
这个目标文件指的是一个包含更多细节的xml文件(
$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml
在这个例子中指的是mybuild.xml)。创建mybuild.xml
. -
在
mybuild.xml
中插入以下内容:<?xml version="1.0" encoding="utf-8"?> <ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib"> <ItemType Name="MYBUILD" DisplayName="My Custom Build" /> </ProjectSchemaDefinitions>
-
将文件扩展名与内容类型关联。这是通过在
mybuild.xml
中添加如下条目来实现的:<FileExtension Name="*.myext" ContentType="MYBUILD" />
-
将内容类型与项目类型关联。这是通过在
mybuild.xml
中添加如下条目来实现的:<ContentType Name="MYBUILD" DisplayName="My Custom Build" ItemType="MYBUILD" />
将项目类型关联到构建目标。在
mybuild.targets
中,将以下内容添加到与PropertyPageSchema相同的ItemGroup中:<AvailableItemName Include="MYBUILD"> <Targets>_MYBUILD</Targets> </AvailableItemName>
定义自定义目标。在这里,您可以映射用于配置构建任务的所有属性和变量。在下一步中,我们将使用一个使用命令行模板的构建任务,因此在我们的目标中,我们将配置实际的命令行。它位于上一步中定义的
ItemGroup
的正下方:<Target Name="_MYBUILD"> <MYBUILD CommandLineTemplate="explorer $(IntDir)"></MYBUILD> </Target>
声明一个自定义构建任务。它位于上一步的
Target
之后:<UsingTask TaskName="MYBUILD" TaskFactory="XamlTaskFactory" AssemblyName="Microsoft.Build.Tasks.v4.0"> <Task>$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml</Task> </UsingTask>
在
mybuild.xml
中增加如下规则:<Rule Name="MYBUILD" PageTemplate="tool" DisplayName="My Custom Build" Order="200"/>
我们刚刚做了什么:项目文件现在包含了一个新的目标定义(mybuild.targets
)。该文件通常包含有关如何执行实际构建的更多信息,但这里它只包含对mybuild.xml
文件的包含。这个mybuild.xml
文件包含一个新的项目类型定义,其内部名称为MYBUILD
,显示名称为My Custom Build
。当项目在Visual Studio中重新打开时,在"项目类型"列表中将出现一个新的项目类型。选择它会将该项的类型设置为MYBUILD
,由于我们目前还没有为这种类型的项定义规则,因此它将在构建中被忽略。
将文件扩展名与自定义项类型MSVC相关联
这分两步完成:
此时,mybuild.xml
看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<ItemType Name="MYBUILD" DisplayName="My Custom Build" />
<FileExtension Name="*.hh" ContentType="MYBUILD" />
<ContentType Name="MYBUILD" DisplayName="My Custom Build" ItemType="MYBUILD" />
</ProjectSchemaDefinitions>
我们刚刚做了什么:Visual Studio现在知道扩展名.myext
包含MYBUILD
类型的数据。它还知道内容类型为MYBUILD
的文件是类型为MYBUILD
的项。一旦项目在Visual Studio中重新打开,当添加扩展名为.myext
的文件时,Visual Studio将自动将项目类型设置为"我的自定义构建";
在自定义项上执行自定义工具MSVC
此时,我们有了一个与自定义项类型相关联的文件扩展名。我们需要将项目类型与一组构建规则相关联。现在看起来是这样的:
<ItemGroup>
<PropertyPageSchema
Include="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml" />
<AvailableItemName Include="MYBUILD">
<Targets>_MYBUILD</Targets>
</AvailableItemName>
</ItemGroup>
命令行将打开一个资源管理器窗口。
这里,我们指的是将在mybuild.xml
文件中定义的任务。
我们刚刚所做的:我们将自定义项目类型映射到一个自定义目标,以及一个打开资源管理器窗口的自定义构建任务。当我们构建.myext
文件时,我们现在可以期待Visual Studio弹出一个资源管理器窗口。
自定义构建
有很多方法可以在属性窗口中添加配置字段,将它们映射到变量并使用它们来配置任务。这里不讨论这个问题,但在顶部提供的链接中进行了讨论。