博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅谈VS编译自定义编译任务—MSBuild Task(csproject)
阅读量:7078 次
发布时间:2019-06-28

本文共 6277 字,大约阅读时间需要 20 分钟。

     在上一篇中我们简单的反编译查看了几种c#语法糖和PostSharp在编译成IL时为我做的MSIL注入。紧接着在这节,要来看的就是MSBuild Task。在我们的代码预编译过程中我们可以创建我们自己的任务Task。下面我们就开始做一个简单的Task。

1:首先需要添加Microsoft.Build.Utilities.v3.5.dll和Microsoft.Build.Framework.dll中引用。在Microsoft.Build.Framework中为我们定义了接口ITask,自定义任务需要去实现这个契约。其定义如下: 

  
public
 
interface
 ITask 
    { 
       IBuildEngine BuildEngine { 
get
set
; } 
       ITaskHost HostObject { 
get
set
; } 
       
bool
 Execute(); 
    }

IBuildEngine 从字义上说是编译引擎,他主要承载了我们的编译生成时的信息和消息,警告,错误等事件注册。而Execute这是我们Task执行体。HostObject 任务关联宿主信息。

在Microsoft.Build.Utilities下Task为我们实现了基本的ITask信息。我们可以从这里继承开始。

下面是一个简单的实现:

using
 System; 
using
 System.Collections.Generic; 
using
 System.Linq; 
using
 System.Text; 
namespace
 FirstBuildTask 
    
public
 
class
 MyBuildTask : Microsoft.Build.Utilities.Task 
    { 
        
private
 
string
 outputFile; 
        [Microsoft.Build.Framework.Required] 
        
public
 
string
 OutputFile 
        { 
            
get
 { 
return
 outputFile; } 
            
set
 { outputFile 
=
 value; } 
        } 
        
public
 
override
 
bool
 Execute() 
        { 
            Log.LogWarning(
"
test message:
"
 
+
 
this
.outputFile); 
            
return
 
true
        } 
    } 
}

下面我们需要关联Task,本人不喜欢污染,所以加到csproject(也可全局所有项目使用)。

下面我们创建一个简单的控制台

程序
using
 System; 
using
 System.Collections.Generic; 
using
 System.Linq; 
using
 System.Text; 
namespace
 BlogSample 
    
class
 Program 
    { 
        
static
 
void
 Main(
string
[] args) 
        { 
            Console.WriteLine(
"
ok
"
); 
            Console.Read(); 
        } 
    } 
}

用记事本形式打开csproject文件:

添加我们的Task声明和任务。(xml标记含义将在后续,这里先看看效果。)

声明Task:

<
UsingTask 
TaskName
="MyBuildTask"
 AssemblyFile
="XXXX\bin\Debug\FirstBuildTask1.dll"
/>

添加任务:

<
Target 
Name
="AfterBuild"
>
 
<
MyBuildTask 
OutputFile
="$(MSBuildProjectFullPath)"
/>
 
  
</
Target
>

修改后的csproject文件形如:

ExpandedBlockStart.gif
View Code
<?
xml version="1.0" encoding="utf-8"
?>
 
<
Project 
ToolsVersion
="3.5"
 DefaultTargets
="Build"
 xmlns
="http://schemas.microsoft.com/developer/msbuild/2003%22> 
  <PropertyGroup> 
    <Configuration Condition="
 '$(Configuration)' 
== 
'' "
>
Debug
</
Configuration
>
 
    
<
Platform 
Condition
=" '$(Platform)' == '' "
>
AnyCPU
</
Platform
>
 
    
<
ProductVersion
>
9.0.30729
</
ProductVersion
>
 
    
<
SchemaVersion
>
2.0
</
SchemaVersion
>
 
    
<
ProjectGuid
>
{844D0C87-9808-4AE9-8906-0382D9DDF88A}
</
ProjectGuid
>
 
    
<
OutputType
>
Exe
</
OutputType
>
 
    
<
AppDesignerFolder
>
Properties
</
AppDesignerFolder
>
 
    
<
RootNamespace
>
BlogSample
</
RootNamespace
>
 
    
<
AssemblyName
>
BlogSample
</
AssemblyName
>
 
    
<
TargetFrameworkVersion
>
v3.5
</
TargetFrameworkVersion
>
 
    
<
FileAlignment
>
512
</
FileAlignment
>
 
  
</
PropertyGroup
>
 
  
<
PropertyGroup 
Condition
=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "
>
 
    
<
DebugSymbols
>
true
</
DebugSymbols
>
 
    
<
DebugType
>
full
</
DebugType
>
 
    
<
Optimize
>
false
</
Optimize
>
 
    
<
OutputPath
>
bin\Debug\
</
OutputPath
>
 
    
<
DefineConstants
>
DEBUG;TRACE
</
DefineConstants
>
 
    
<
ErrorReport
>
prompt
</
ErrorReport
>
 
    
<
WarningLevel
>
4
</
WarningLevel
>
 
  
</
PropertyGroup
>
 
  
<
PropertyGroup 
Condition
=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "
>
 
    
<
DebugType
>
pdbonly
</
DebugType
>
 
    
<
Optimize
>
true
</
Optimize
>
 
    
<
OutputPath
>
bin\Release\
</
OutputPath
>
 
    
<
DefineConstants
>
TRACE
</
DefineConstants
>
 
    
<
ErrorReport
>
prompt
</
ErrorReport
>
 
    
<
WarningLevel
>
4
</
WarningLevel
>
 
  
</
PropertyGroup
>
 
  
<
ItemGroup
>
 
    
<
Reference 
Include
="System"
 
/>
 
    
<
Reference 
Include
="System.Core"
>
 
      
<
RequiredTargetFramework
>
3.5
</
RequiredTargetFramework
>
 
    
</
Reference
>
 
    
<
Reference 
Include
="System.Xml.Linq"
>
 
      
<
RequiredTargetFramework
>
3.5
</
RequiredTargetFramework
>
 
    
</
Reference
>
 
    
<
Reference 
Include
="System.Data.DataSetExtensions"
>
 
      
<
RequiredTargetFramework
>
3.5
</
RequiredTargetFramework
>
 
    
</
Reference
>
 
    
<
Reference 
Include
="System.Data"
 
/>
 
    
<
Reference 
Include
="System.Xml"
 
/>
 
  
</
ItemGroup
>
 
  
<
ItemGroup
>
 
    
<
Compile 
Include
="DisposeSubstance.cs"
 
/>
 
    
<
Compile 
Include
="Program.cs"
 
/>
 
    
<
Compile 
Include
="Properties\AssemblyInfo.cs"
 
/>
 
  
</
ItemGroup
>
 
  
<
Import 
Project
="$(MSBuildToolsPath)\Microsoft.CSharp.targets"
 
/>
 
<
UsingTask 
TaskName
="MyBuildTask"
 AssemblyFile
="XXXXX\bin\Debug\FirstBuildTask1.dll"
/>
 
  
<
Target 
Name
="BeforeBuild"
>
 
  
</
Target
>
 
  
<
Target 
Name
="AfterBuild"
>
 
<
MyBuildTask 
OutputFile
="$(MSBuildProjectFullPath)"
/>
 
  
</
Target
>
 
</
Project
>

此时我们可以用VS重新加载编译或者是MSBuild控制台编译:

效果如下:

上边红线注释的就是我们的Task所做的警告和输出路径的提示。

我们已经完成了一个简单Task,但还遗留这MsBuild配置,下面将简单的描述。

1:UsingTask:定义:<UsingTask TaskName="TaskName" AssemblyName = "AssemblyName" TaskFactory = "ClassName" Condition="'String A'=='String B'" />

描述我们的任务的程序集,任务类等信息,具体参见。

属性 说明

AssemblyName

AssemblyNameAssemblyFile 属性是必需的。

要加载的程序集的名称。尽管 AssemblyName 属性不是必需的,但它接受强名称程序集。使用此属性等效于通过 .NET Framework 中的 方法加载程序集。

如果使用了 AssemblyFile 属性,便不能使用此属性。

AssemblyFile

AssemblyNameAssemblyFile 属性是必需的。

程序集的文件路径。此属性既接受完整路径,也接受相对路径。相对路径是相对于当前项目目录的路径。使用此属性等效于通过 .NET Framework 中的 方法加载程序集。

如果使用了 AssemblyName 属性,便不能使用此属性。

TaskName

必选的属性。

要从程序集中引用的任务的名称。如果可能存在多义性,则此属性应该始终指定完整的命名空间。如果存在多义性,MSBuild 将选择任意匹配方式,该匹配方式可能产生意外的结果。

Condition

可选的属性。

要计算的条件。有关更多信息,请参见 。

在系统中为我们定义了很多Task,有:

:描述
AL 任务及其参数。 :包装 aspnet_compiler.exe,它是预编译 ASP.NET 应用程序的实用工具。 :为项分配区域性标识符。 :调用项目文件中的目标。 :描述
Copy 任务及其参数。 :描述
CreateItem 任务及其参数。 :描述
CreateProperty 任务及其参数。 :描述
Csc 任务及其参数。 :描述
Delete 任务及其参数。 :根据计算的条件语句停止生成操作并记录错误。 :描述
Exec 任务及其参数。 :确定指定项集合中的哪些项存在于指定的文件夹及其所有子文件夹中。 :描述
GenerateApplicationManifest 任务及其参数。 :提供一种自动化方式来检测、下载和安装应用程序及其必备组件。 :描述
GenerateDeployManifest 任务及其参数。 :将 .txt 和 .resx 文件转换为公共语言运行库二进制 .resources 文件。 :从指定的文件检索程序集标识并输出标识信息。 :检索 .NET Framework 程序集的路径。 :检索 .NET Framework SDK 的路径。 :描述
LC 任务及其参数。 :描述
MakeDir 任务及其参数。 :在生成期间记录消息。 :描述 MSBuild 任务及其参数。 :从文本文件读取项列表。 :描述
RegisterAssembly 任务及其参数。 :描述
RemoveDir 任务及其参数。 :描述
ResGen 任务及其参数。 :描述
ResolveAssemblyReference 任务及其参数。 :描述
ResolveCOMReference 任务及其参数。 :确定强名称密钥源 :解析本机引用。 :为指定程序集中的类型创建一个 XML 序列化程序集。 :使用指定证书对指定文件进行签名。 :描述
Touch 任务及其参数。 :描述
UnregisterAssembly 任务及其参数。 ”描述
Vbc 任务及其参数。 “描述
VCBuild 任务及其参数。 :根据计算的条件语句在生成期间记录警告。 :将指定项写入指定的文本文件。 其实很多我都不知道,我经常是用的时候在去查MSDN:

2:Target:定义

<
Target 
Name
="Target Name"
 DependsOnTargets
="DependentTarget"
 Inputs
="Inputs"
 Outputs
="Outputs"
 Condition
="'String A' == 'String B'"
>
 
<
Task
>
... 
</
Task
>
 
<
OnError... 
/>
 
</
Target
>

描述了我们的目标:可以包含0个多个任务。

属性

属性 说明

Name

必选的属性。

目标的名称。

DependsOnTargets

可选的属性。

在执行此目标或者进行顶级依赖项分析之前必须执行的目标。多个目标之间用分号分隔。

Inputs

可选的属性。

此目标的项输入。此属性中的项用作顶级依赖项分析中的输入。

Outputs

可选的属性。

此目标的预期输出。可以通过对输入项应用转换来生成输出项。有关转换的更多信息,请参见 。

Condition

可选的属性。

要计算的条件。如果条件的计算结果为 false,目标将不会执行该目标的体或者在 DependsOnTargets 属性中设置的任何目标的体。有关条件的更多信息,请参见

msdn:

参考文献:

MSBuild概念:

转载地址:http://mjdml.baihongyu.com/

你可能感兴趣的文章
数据中心基础设施规划设计16问答
查看>>
JavaScript常用开发工具集合
查看>>
加快网络信息安全配套工程建设
查看>>
AMD全新企业级CPU与APU路线图曝光
查看>>
富瑞:微博财报将超预期 广告主预算正向微博迁移
查看>>
听CIO们关于与经营管理同事协同工作的建议
查看>>
论国产化芯片出路 破“玻璃巨人之危”
查看>>
软件测试管理的一点经验
查看>>
FB等社交媒体都争做原创视频 是为了广告费吗?
查看>>
运营商积极布局物联网 万亿级市场有望启动
查看>>
云平台大数据助推昆明市“互联网+农业”行动实施
查看>>
他将网络安全威胁比喻成癌症
查看>>
视频监控热成像技术在民用领域的广泛应用
查看>>
《大众创业做电商——淘宝与微店 开店 运营 推广 一册通》一一2.1 电子商务的发展历史...
查看>>
Light Table —— 多语言集成开发环境
查看>>
未来桌面 PC 会消失吗?
查看>>
换个 timeline 看知乎
查看>>
《UG NX10中文版完全自学手册》——2.6 常用工具
查看>>
《深入理解Hadoop(原书第2版)》——1.5我们能处理多大的数据量
查看>>
《CCNP TSHOOT 300-135认证考试指南》——6.9节三层EtherChannel故障工单
查看>>