在上一篇浅谈.NET编译时注入(C#-->IL)中我们简单的反编译查看了几种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:
添加任务:
修改后的csproject文件形如:
上边红线注释的就是我们的Task所做的警告和输出路径的提示。
我们已经完成了一个简单Task,但还遗留这MsBuild配置,下面将简单的描述。
1:UsingTask:定义:<UsingTask TaskName="TaskName" AssemblyName = "AssemblyName" TaskFactory = "ClassName" Condition="'String A'=='String B'" />
描述我们的任务的程序集,任务类等信息,具体参见http://msdn.microsoft.com/zh-cn/library/t41tzex2.aspx。
属性 | 说明 |
---|---|
AssemblyName |
AssemblyName 或 AssemblyFile 属性是必需的。 要加载的程序集的名称。尽管 AssemblyName 属性不是必需的,但它接受强名称程序集。使用此属性等效于通过 .NET Framework 中的 Load 方法加载程序集。 如果使用了 AssemblyFile 属性,便不能使用此属性。 |
AssemblyFile |
AssemblyName 或 AssemblyFile 属性是必需的。 程序集的文件路径。此属性既接受完整路径,也接受相对路径。相对路径是相对于当前项目目录的路径。使用此属性等效于通过 .NET Framework 中的 LoadFrom 方法加载程序集。 如果使用了 AssemblyName 属性,便不能使用此属性。 |
TaskName |
必选的属性。 要从程序集中引用的任务的名称。如果可能存在多义性,则此属性应该始终指定完整的命名空间。如果存在多义性,MSBuild 将选择任意匹配方式,该匹配方式可能产生意外的结果。 |
Condition |
可选的属性。 要计算的条件。有关更多信息,请参见 MSBuild 条件。 |
在系统中为我们定义了很多Task,有:
2:Target:定义
描述了我们的目标:可以包含0个多个任务。
属性 | 说明 |
---|---|
Name |
必选的属性。 目标的名称。 |
DependsOnTargets |
可选的属性。 在执行此目标或者进行顶级依赖项分析之前必须执行的目标。多个目标之间用分号分隔。 |
Inputs |
可选的属性。 此目标的项输入。此属性中的项用作顶级依赖项分析中的输入。 |
Outputs |
可选的属性。 此目标的预期输出。可以通过对输入项应用转换来生成输出项。有关转换的更多信息,请参见 MSBuild 转换。 |
Condition |
可选的属性。 要计算的条件。如果条件的计算结果为 false,目标将不会执行该目标的体或者在 DependsOnTargets 属性中设置的任何目标的体。有关条件的更多信息,请参见 MSBuild |
msdn:http://msdn.microsoft.com/zh-cn/library/t50z2hka(VS.80).aspx
参考文献:
http://msdn.microsoft.com/zh-cn/library/t41tzex2.aspx
http://msdn.microsoft.com/zh-cn/library/t50z2hka(VS.80).aspx
http://msdn.microsoft.com/zh-cn/library/ms171466(v=VS.80).aspx
http://msdn.microsoft.com/zh-cn/library/7z253716(v=VS.80).aspx
http://msdn.microsoft.com/zh-cn/library/ms164313(v=VS.80).aspx
http://msdn.microsoft.com/zh-cn/library/t9883dzc(v=VS.80).aspx
http://msdn.microsoft.com/zh-cn/library/ms171464(v=VS.80).aspx
MSBuild概念:http://msdn.microsoft.com/zh-cn/library/ms171451(v=VS.80).aspx