MSBuild入门

2023-10-30

MSBuild是什么?

MSBuild全称(Microsoft Build Engine),是用于构建应用程序的平台。您可能不知道它,但是如果您在使用VS做开发,那么一定时时刻刻在使用它。因为是它在背后为你管理生成你的项目文件。当新建一个项目时,注意下项目文件夹中的*.*proj文件就是为MSBuild提供的,这是个文本文件,基于XML格式,里面包含有项目所包含的文件,生成配置,输出配置等信息。当把一个文件或者图片等添加到项目中,就会在这里添加一个描述,反之则删除一个描述信息;在项目属性页所做的配置也会在这里存储。

为何去了解MSBuild

想去了解这个源于以前学WPF时的疑惑(当时就想从MSBuild下手了,一直没精力,拖到现在),因为不知道XAML为何就跑到生成的程序集,以及这个XAML标记最后变成什么,WPF是如何处理这些XAML标签与C#代码的?一般写代码时我都会清楚的知道这个代码最后经由编译器变成了什么,这样心里比较底。但是这个XAML,是看不透,看不透就心里堵得慌,不踏实,我比较喜欢刨根问底,所以就想到通过这个入口探个究竟。

我想从MSBuild中得到什么

第一解决我上面说疑惑;
第二理解项目中这些文件是如何组织在一起并生成最终程序的(就像在WPF上Build是生成出来exe,而WP7则是出来一个XAP包,为何?);
第三了解到为止,以看懂理解为目的,不做深入研究。

MSBuild基本概念

MSBuild有四个基本块(属性、项、任务、目标):

MSBuild属性:   属性是一些键/值对,主要用来存储一些配置信息。
MSBuild   项:   主要是存储一些项目文件信息,以及文件的元数据信息(如版本号)。
MSBuild任务:   Build过程中的一些原子操作(如CSC、MakeDir)
MSBuild目标:   按特定的顺序将任务组织在一起,并允许在命令行单独指定各个部分。

一句话总结MSBuild的作用:利用配置信息对项目文件实施特定顺序的操作。

MSBuild属性

属性声明方式:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!--根元素,表示一个项目-->
 3 <!--DefaultTargets用于定默认执行的目标-->
 4 <Project DefaultTargets="build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 5   <!--属性都要包含在PropertyGroup元素内部-->
 6   <PropertyGroup>
 7     <!--声明一个"linianhui"属性,其值为"hello world"-->
 8     <linianhui>hello world</linianhui>
 9   </PropertyGroup>
10   <!--目标-->
11   <Target Name="build">
12     <!--MSBuild提供的一个内置任务,用于生成记录信息用$(属性名)来引用属性的值-->
13     <Message Text="$(linianhui)"></Message>
14   </Target>
15 </Project>

保存此文件到d:\helloworld.xml文件。打开CMD窗口,输入MSBuild helloworld.xml:

打印出“linianhui”属性的值。MSBuild提供一些保留属性,可以方便的引用$,如$(MSBuildProjectFile)将返回项目文件的完整名(helloworld.xml)。其他的保留属性可以查阅MSDN帮助文档。

MSBuild项

 项声明方式:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!--项都要包含在ItemGroup元素内部-->
  <ItemGroup>
    <!--声明一个"CSFile"的项,Include表示引入"csfile1.cs"文件-->
    <CSFile Include="csfile1.cs">
      <!--Version表示项的元数据(附加信息)-->
      <Version>1.0.0.0</Version>
    </CSFile>
    <!--也可用";"一次引入多个文件-->
    <CSFile Include="csfile2.cs;csfile3.cs"/>
  </ItemGroup>
  <Target Name="build">
    <!--@引用项的值,默认以";"分割开-->
    <!--输出"csfile1.cs;csfile2.cs;csfile3.cs"-->
    <Message Text="@(CSFile)"></Message>
    <!--可以加第二个参数替换默认的";"分隔符-->
    <!--输出"csfile1.cs+csfile2.cs+csfile3.cs"-->
    <Message Text="@(CSFile,'+')"></Message>
    <!--%引用项的元数据,输出"1.0.0.0"-->
    <Message Text="%(CSFile.Version)"></Message>
  </Target>
</Project>

MSBuild任务

上述Msaage就是一个任务,用于打印信息,常用的一些还包括CSC、MakeDir、Copy等等,大多任务都是有输出信息的,这些信息可以通过OutPut元素存储在属性或者项中。先写如下CS代码:

1 //存为d:\MSBuildDemo.cs
2 public class MSBuildDemo
3 {
4     static void Main()
5     {
6         System.Console.WriteLine("MSBuild组织编译");
7     }
8 }

然后更改项目文件如下:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <Project DefaultTargets="build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 3   <ItemGroup>
 4     <!--指定要编译的文件-->
 5     <CSFile Include="MSBuildDemo.cs"/>
 6   </ItemGroup>
 7   <Target Name="build">
 8     <!--使用Csc任务,对应csc编译器-->
 9     <!--Sources属性表示要编译的文件集合-->
10     <!--TargetType表示编译目标类型,对应csc编译器的/target参数-->
11     <Csc Sources="@(CSFile)"
12          TargetType="exe">
13       <!--OutputAssembly为csc的输出参数-->
14       <!--PropertyName表示把TaskParameter属性所指定的输出参数的值存储到outputExeName这个属性中-->
15       <!--Output还有一个ItemName属性,表示存储到一个项中-->
16       <Output TaskParameter="OutputAssembly" PropertyName="outputExeFileName"/>
17     </Csc>
18     <!--Message任务就可以使用csc所导出的属性outputExeFileName了-->
19     <!--输出MSBuildDemo.exe-->
20     <Message Text="$(outputExeFileName)"/>
21     <!--Exec任务可以运行带有指定程序(可加参数)或命令-->
22     <!--运行刚从MSBuildDemo.cs源文件编译好的程序-->
23     <!--运行结果为"MSBuild组织编译"-->
24     <Exec Command="$(outputExeFileName)"></Exec>
25   </Target>
26 </Project>

用MSbuild执行此项目文件,如期正确打印信息。

MSBuild目标

上面的一个例子中Target元素就是MSBuild目标,此目标按照编译源代码、打印编译好的程序文件名、执行该文件这个顺序组织了这三个任务。这就是目标所要做的事情。先简单介绍到这里吧,关于(属性、项、任务、目标)的一些扩展信息会在下一篇介绍。如有错误之处,欢迎指正!

注:以上资料全部来自MSDN帮助文档。https://docs.microsoft.com/zh-cn/visualstudio/msbuild/msbuild

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MSBuild入门 的相关文章

  • InvalidOperationException - 对象当前正在其他地方使用 - 红十字

    我有一个 C 桌面应用程序 其中我连续创建的一个线程从源 实际上是一台数码相机 获取图像并将其放在 GUI 中的面板 panel Image img 上 这必须是另一个线程 如它是控件的代码隐藏 该应用程序可以工作 但在某些机器上 我会在随
  • 用于代数简化和求解的 C# 库 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 网络上有很多代数求解器和简化器 例如 algebra com 上不错的代数求解器和简化器 然而 我正在
  • 未提供参数时如何指定 C# System.Commandline 行为?

    在我的控制台应用程序中 当未提供控制台参数时 将执行我指定列表 在本例中为参数 3 的任何处理程序 调用该处理程序时 布尔参数设置为 false 但对我来说 根本不调用它更有意义 如何防止这种情况发生并显示帮助文本 using System
  • 错误:表达式不产生值

    我尝试将以下 C 代码转换为 VB NET 但在编译代码时出现 表达式不产生值 错误 C Code return Fluently Configure Mappings m gt m FluentMappings AddFromAssemb
  • 复制目录内容

    我想将目录 tmp1 的内容复制到另一个目录 tmp2 tmp1 可能包含文件和其他目录 我想使用C C 复制tmp1的内容 包括模式 如果 tmp1 包含目录树 我想递归复制它们 最简单的解决方案是什么 我找到了一个解决方案来打开目录并读
  • 单个对象的 Monogame XNA 变换矩阵?

    我读过一些解释 XNA Monogame 变换矩阵的教程 问题是这些矩阵应用于 SpriteBatch Begin matrix 这意味着所有 Draw 代码都将被转换 如何将变换矩阵应用于单个可绘制对象 就我而言 我想转换滚动背景 使其自
  • 回发后刷新时提示确认表单重新提交。我做错了什么?

    我有一个以空白 默认状态启动的仪表板 我让用户能够将保存的状态加载到仪表板中 当他们单击 应用 按钮时 我运行以下代码 function CloseAndSave var radUpload find radUpload1ID var in
  • 如何使用 LINQ2SQL 连接两个不同上下文的表?

    我的应用程序中有 2 个数据上下文 不同的数据库 并且需要能够通过上下文 B 中的表的右连接来查询上下文 A 中的表 我该如何在 LINQ2SQL 中执行此操作 Why 我们正在使用 SaaS 产品来跟踪我们的时间 项目等 并希望向该产品发
  • 标准化 UTF-8 到底是什么?

    The 重症监护室项目 http userguide icu project org transforms normalization 现在也有一个PHP库 http us php net manual en class normalize
  • 我可以使用 moq Mock 来模拟类而不是接口吗?

    正在经历https github com Moq moq4 wiki Quickstart https github com Moq moq4 wiki Quickstart 我看到它 Mock 一个接口 我的遗留代码中有一个没有接口的类
  • Azure 辅助角色“请求输入之一超出范围”的内部异常。

    我在辅助角色中调用 CloudTableClient CreateTableIfNotExist 方法 但收到一个异常 其中包含 请求输入之一超出范围 的内部异常 我做了一些研究 发现这是由于将表命名为非法表名引起的 但是 我尝试为我的表命
  • AES 128 CBC 蒙特卡罗测试

    我正在 AES 128 CBC 上执行 MCT 如中所述http csrc nist gov groups STM cavp documents aes AESAVS pdf http csrc nist gov groups STM ca
  • 如何设置 log4net 每天将我的文件记录到不同的文件夹中?

    我想将每天的所有日志保存在名为 YYYYMMdd 的文件夹中 log4net 应该根据系统日期时间处理创建新文件夹 我如何设置它 我想将一天中的所有日志保存到 n 个 1MB 的文件中 我不想重写旧文件 但想真正拥有一天中的所有日志 我该如
  • 动态添加 ASP.Net 控件

    我有一个存储过程 它根据数据库中存储的记录数返回多行 现在我想有一种方法来创建 div 带有包含该行值的控件的标记 如果从数据库返回 10 行 则 10 div 必须创建标签 我有下面的代码来从数据库中获取结果 但我不知道如何从这里继续 S
  • C++ 函数重载类似转换

    我收到一个错误 指出两个重载具有相似的转换 我尝试了太多的事情 但没有任何帮助 这是那段代码 CString GetInput int numberOfInput BOOL clearBuffer FALSE UINT timeout IN
  • 调用堆栈中的“外部代码”是什么意思?

    我在 Visual Studio 中调用一个方法 并尝试通过检查调用堆栈来调试它 其中一些行标记为 外部代码 这到底是什么意思 方法来自 dll已被处决 外部代码 意味着该dll没有可用的调试信息 你能做的就是在Call Stack窗口中单
  • System.IO.FileNotFoundException:找不到网络路径。在 Windows 7 上使用 DirectoryEntry 对象时出现异常

    我正在尝试使用 DirectoryEntry 对象连接到远程 Windows 7 计算机 这是我的代码 DirectoryEntry obDirEntry new DirectoryEntry WinNT hostName hostName
  • 我的班级应该订阅自己的公共活动吗?

    我正在使用 C 3 0 遵循标准事件模式我有 public event EventHandler
  • 从列表中选择项目以求和

    我有一个包含数值的项目列表 我需要使用这些项目求和 我需要你的帮助来构建这样的算法 下面是一个用 C 编写的示例 描述了我的问题 int sum 21 List
  • 如何将 PostgreSql 与 EntityFramework 6.0.2 集成? [复制]

    这个问题在这里已经有答案了 我收到以下错误 实体框架提供程序类型的 实例 成员 Npgsql NpgsqlServices Npgsql 版本 2 0 14 2 文化 中性 PublicKeyToken 5d8b90d52f46fda7 没

随机推荐

  • java 文件下载进度条_下载文件时显示动态的进度条(前端easyUI,后台java)

    最近有点闲 我们的架构师让我在文件下载时显示进度条 咳咳 自从组里来了前端妹纸后 好久没写前端代码了 架构师推荐的用监听器 链接找不到了 实现得有点复杂 我没太看懂 继续百度 看到了 在下载时计算进度 然后把进度放到session中 另外写
  • 查看哪个进程占用了8005端口,并杀死占用端口的进程。

    查看哪个进程占用了8005端口 netstat ano findstr 8005 返回进程号 通过进程号杀死占用端口的进程 taskkill PID 19288 F 杀死该进程 F是强制删除
  • C++—返回值优化

    返回值优化 Return value optimization 缩写为RVO 是C 的一项编译优化技术 即删除保持函数返回值的临时对象 这可能会省略两次复制构造函数 当一个函数返回一个对象实例 一个临时对象将被创建并通过复制构造函数把目标对
  • 这些Android面试题,成就你高薪就业。

    前言 这些题目都是面试必答题 看看你还有哪些是没有掌握到的 1 说下你所知道的设计模式与使用场景 建造者模式 观察者模式 代理模式 门面模式 单例模式 生产者消费者模式 2 Java语言的特点与OOP思想 这个通过对比来描述 比如面向对象和
  • Leetcode 95. 不同的二叉搜索树 II

    文章目录 题目 代码 9 21 首刷看解析 题目 Leetcode 95 不同的二叉搜索树 II 代码 9 21 首刷看解析 class Solution public vector
  • vue实现动态路由--后台返回路由表(并解决页面刷新,路由找不到的问题)

    先大致说一下自己的思路 其实后台返回的权限表跟我们前端自己配置的路由格式是差不多的 格式可以跟后台沟通 我们需要做的是根据后台返回的路由 然后进行遍历 生成一个本地的路由表 然后利用Router addRouters 这个方法 把我们新生成
  • Jmeter-Android手机端脚本录制

    温馨提示 电脑和手机在同一网络段上 1 打开Jmeter工具 新建一个HTTP代理服务器 2 然后再新建一个线程组 3 在线程组中添加录制控制器 4 打开模拟器 设置 WiFi 长按 修改网络
  • 辅助模块加速收敛,精度大幅提升 移动端实时的NanoDet-Plus来了

    Nanodet目标检测模型完成自动捡球机器人 从零开始 带你用Nanodet目标检测模型完成自动捡球机器人 古月居 开源地址 https github com Coolog Nanodet Robot PathPlanning 作者提出 N
  • 技术分享|SQL和 NoSQL数据库之间的差异:MySQL(VS)MongoDB

    技术分享 SQL和 NoSQL数据库之间的差异 什么是SQL和NoSQL 一 什么是SQL 二 什么是NoSQL SQL VS NoSQL 针对SQL和NoSQL的区别 将基于不同的方面进行比较 MySQL VS MongoDB 在当今市场
  • forEach()退出循环的方法

    在for循环中退出循环有3种方式 return 终止 break 退出整个循环 continue 退出当次循环 forEach 只能识别上面三种退出循环中的return 其它都识别不了 且return在forEach 中相当于continu
  • ThreadLocal失效

    在JDK中 解决线程冲突问题 有两种解决方案 l 给临界区加锁 l 本地化临界区 第一种解决方案的典型代表是Synchonized 第二种的典型代表是ThreadLocal 而CopyOnWrite是这两种方案的融合 ThreadLocal
  • Arduino通过L298N红板控制板控制直流电机

    在Arduino论坛上看到很多人都做过智能小车 有两轮的 有四轮的 功能也是多种多样 有寻迹 壁障 无线遥控 红外遥控的 其实小车就是个底盘或者载体 然后可以根据需要向小车上加功能模块 于是我在淘宝上买了一个四轮小车的架子 里面包括四个轮子
  • python解包的概念_如何以编程方式为解包结构?

    我试图用Python读取和解析一个二进制文件 在 问题是文件中的数据可以是little endian或big endian格式 也可以是32位或64位的值 在文件头中有几个字节指定数据格式和大小 假设我已经读过这些 并且知道格式和大小 然后
  • SWM32系列教程7-I2C及其应用

    SWM32S单片机有2个I2C外设 其特点如下 支持最高1MHZ速率主机模式 支持最高400KHZ速率从机模式 支持7位或10位地址 波特率可配置 支持中断功能 今天就以驱动电容触摸芯片GT911为例 介绍一下I2C模块的使用 配置I2C之
  • 前端实现打印功能

    目录 方法一 window print 方法二 利用iframe iframe contentWindow print 方法三 使用第三方库或插件 提供一个完整的范例 1 设计打印布局 2 创建打印版本 3 使用JavaScript控制打印
  • C++核心编程 之类和对象(二)

    目录 1 2 对象的初始化和清理 1 2 1 构造函数和析构函数 构造函数语法 析构函数语法 1 2 2 构造函数的分类和调用 1 2 3 拷贝构造函数调用时机 1 2 4 构造函数调用规则 1 2 5 深拷贝与浅拷贝 1 2 6 初始化列
  • 1-Linux_虚拟机VMware 15安装教程

    虚拟机VMware 15安装教程 https www onlinedown net soft 2062 htm 1 由上面的网址下载VMware 15后双击运行安装程序点击下一步 进行安装 2 在最终用户许可协议界面选中 我接受许可协议中的
  • 为什么要用TSubClassOf

    2019独角兽企业重金招聘Python工程师标准 gt gt gt TSubclassOf 是提供 UClass 类型安全性的模板类 例如您在创建一个投射物类 允许设计者指定伤害类型 您可只创建一个 UClass 类型的 UPROPERTY
  • vsocde vue snippet 设置

    vue snippt 设置 建议下在一个 vetur extensions 1 首先打开 vue json 文件 ctrl p 搜索 vue json 文件 enter File gt preferences gt User sneppts
  • MSBuild入门

    MSBuild是什么 MSBuild全称 Microsoft Build Engine 是用于构建应用程序的平台 您可能不知道它 但是如果您在使用VS做开发 那么一定时时刻刻在使用它 因为是它在背后为你管理生成你的项目文件 当新建一个项目时