一切福田,不離方寸,從心而覓,感無不通。

Category Archives: Asp.net

C# 代码规范和质量检查工具 StyleCop.Analyzers

简介 原来一直用 ReSharper 来进行代码质量检查,不过毕竟是收费的,所以想找个免费的可以推广给公司的同事也一起用。搜索了一下,找到了StyleCop,但是我在 VS 2015里安装 StyleCop 或者通过 Nuget 包安装 StyleCop.MSBuild,虽然编译以后能把 warning 显示在 Error List 中,但是无法通过 项目—右键 配置 StyleCop 的规则,最终在找到了一个 StyleCopAnalyzers 也算是 StyleCop 的新版本吧。 主要使用了 Visual Studio 2015’s Roslyn 分析工具,带来了以下的好处: 可以支持 C# 6 使用 Roslyn 解析器,减少了自定义解析器的性能消耗 当你写代码的时候解析器就会运行,当你编译的时候也会运行(不需要再设置 msbuild 任务或者安装任何 vs 插件)   安装 安装的话比较简单,在项目里管理 NuGet 包,输入 StyleCop.Analyzers 然后安装就可以了 安装完成就直接可以看到效果了,StyleCop.Analyzers 会像 ReSharper 那样在你写代码的时候就提示错误,而不用编译以后才发现错误了。 不过编译以后还是会把所有的错误提示显示出来   配置自定义规则 在上面的图片里,可以看到我的项目一共有32个 StyleCop 警告,下面我们就把 SA1652 警告去除。 找到引用里得 Analyzer,右键点击 Open Active Rule Set,就可以打开规则表 然后找到 StyleCop.Analyzers 的规则 SA1652,取消勾选,然后保存。 最终会在项目里生成一个 .ruleset 后缀的文件就是我们的自定义规则。 编译以后查看效果,就会发现前面提示的 SA1652 的警告已经没有了。   from:https://blog.csdn.net/xiaoxiao520c/article/details/76585609

龙生   19 Jun 2018
View Details

C# 导出 Excel 的各种方法总结

第一种:使用 Microsoft.Office.Interop.Excel.dll 首先需要安装 office 的 excel,然后再找到 Microsoft.Office.Interop.Excel.dll 组件,添加到引用。

第一种方法性能实在是不敢恭维,而且局限性太多。首先必须要安装 office(如果计算机上面没有的话),而且导出时需要指定文件保存的路径。也可以输出到浏览器下载,当然前提是已经保存写入数据。   第二种:使用 Aspose.Cells.dll 这个 Aspose.Cells 是 Aspose 公司推出的导出 Excel 的控件,不依赖 Office,商业软件,收费的。 可以参考:http://www.cnblogs.com/xiaofengfeng/archive/2012/09/27/2706211.html#top

设置单元格格式为文本方法:

第二种方法性能还不错,而且操作也不复杂,可以设置导出时文件保存的路径,还可以保存为流输出到浏览器下载。   第三种:Microsoft.Jet.OLEDB 这种方法操作 Excel 类似于操作数据库。下面先介绍一下连接字符串:

Provider:驱动程序名称 Data Source:指定 Excel 文件的路径 Extended Properties:Excel 8.0 针对 Excel 2000 及以上版本;Excel 12.0 针对 Excel 2007 及以上版本。 HDR:Yes 表示第一行包含列名,在计算行数时就不包含第一行。NO 则完全相反。 IMEX:0 写入模式;1 读取模式;2 读写模式。如果报错为“不能修改表 sheet1 的设计。它在只读数据库中”,那就去掉这个,问题解决。

这种方法需要指定一个已经存在的 Excel 文件作为写入数据的模板,不然的话就得使用流创建一个新的 Excel 文件,但是这样是没法识别的,那就需要用到 Microsoft.Office.Interop.Excel.dll 里面的 Microsoft.Office.Interop.Excel.Workbook.SaveCopyAs() 方法另存为一下,这样性能也就更差了。 使用操作命令创建的表都是在最后面的,前面的也没法删除(我是没有找到方法),当然也可以不再创建,直接写入数据也可以。   第四种:NPOI NPOI 是 POI 项目的.NET版本,它不使用 Office COM 组件,不需要安装 Microsoft Office,目前支持 Office 2003 和 2007 版本。 NPOI 是免费开源的,操作也比较方便,下载地址:http://npoi.codeplex.com/

PS:操作 2003 版本需要添加 NPOI.dll […]

龙生   11 Jun 2018
View Details

将 ASP.NET MVC 应用程序迁移到 Windows 容器

在 Windows 容器中运行现有的 .NET Framework 应用程序不需要对应用程序进行任何更改。 若要在 Windows 容器中运行应用程序,请创建包含应用程序的 Docker 映像,然后启动容器。 本主题介绍了如何获取现有的 ASP.NET MVC 应用程序,并在 Windows 容器中进行部署。 从现有的 ASP.NET MVC 应用程序入手,然后使用 Visual Studio 生成已发布的资产。 使用 Docker 创建包含并运行应用程序的映像。 转到在 Windows 容器中运行的网站,验证应用程序是否正常运行。 本文可确保基本了解 Docker。 若要了解 Docker,请参阅 Docker 概述。 在容器中运行的应用程序是一个随机回答问题的简单网站。 此应用程序是一款不具备身份验证或数据库存储的基本 MVC 应用程序,让你可以专心处理将 Web 层移到容器中。 后续主题将演示如何在容器化应用程序中移动和管理永久性存储。 移动应用程序涉及以下步骤: 创建发布任务以生成映像资产。 生成将运行应用程序的 Docker 映像。 启动用于运行映像的 Docker 容器。 使用浏览器验证应用程序。 完成的应用程序位于 GitHub 上。 系统必备 开发计算机必须运行 Windows 10 周年更新(或更高版本)或 Windows Server 2016(或更高版本)。 用于 Windows 的 Docker – 稳定版 1.13.0 或 1.12 beta 版本 26(或更高版本) Visual Studio 2017。 重要 如果使用的是 Windows Server 2016,请按容器主机部署 – Windows Server 中的说明操作。 安装并启动 Docker 后,右键单击托盘图标,然后选择“切换到 Windows 容器”。 必须先这样做,才能在 Windows 上运行 Docker 映像。 此命令需要几秒钟执行: 发布脚本 将需要加载到 Docker 映像中的所有资产都汇集到一处。 可以使用 […]

龙生   08 Jun 2018
View Details

大话微服务架构之微服务框架微软ServiceFabric正式开源(三)

选择315这天分享一个好框架-ServiceFabric,它于昨天正式开源了! 微软的 Azure Service Fabric 的官方博客在2017.3.24日发布了一篇博客 Service Fabric .NET SDK goes open source ,介绍了社区呼声最高的 Service Fabric 开源的情况以及当前的情况,当时开源了 Service Fabric的.NET SDK 部分,社区一直在期盼着 Service Fabric 的正式开源,经过了一年漫长的等待,2018年3月14日微软终于开源了 Service Fabric ,而且是以 MIT 许可下开放源代码,在官方博客宣布 https://blogs.msdn.microsoft.com/azureservicefabric/2018/03/14/service-fabric-is-going-open-source。 目前微软在 Github 上的开源地址是 https://github.com/Microsoft/service-fabric,目前的代码构建适用于 Linux 的 Service Fabric ,运行基本测试,有问题可以在上面提交 issue 和 PR 了,Windows 构建环境以及完整的 CI 环境还没有迁移过来。Windows 内部为 Service Fabric 开发了将近十年的内部服务,其中大部分时间都是微软内部平台,比如 Office365,Azure Stack 平台等,这意味着我们有近十年的内部微软工具可以在迁移之前完成迁移和流程细化,逐步全部开源,以后全部开发都在开源模式下进行开发工作。 微软去年漫长的一年时间里也开放了非常多的代码,包括包括 Reliable Services,Reliable Actors 和 ASP.NET Core 集成库,Azure 基础架构服务以及 Azure SQL DB,Azure Cosmos DB 和 Cortana 等大型解决方案都在使用 Service Fabric 构建。 Service Fabric 会带来如下好处: 支持创建无状态和有状态的微服务,通过云平台来伸缩他们,以应对高复杂度、低延迟、数据密集的情况 通过应用程序级别的感知和洞察,为微服务带来编排和自动化的优势 解决分布式系统诸如状态管理这样的难点,为开发人员提供应用程序生命周期管理的能力以便随着业务的增长无需重构系统架构 相关工具会集成到 Visual Studio 中,也会提供相应命令行工具,以便开发人员能够快速和轻易地上手 同时支持.NET和Java,这个特性特别适合目前国内原来很多投资于 .NET 平台。 那么接下来,我们主要来详细看下Service Fabric是什么?有哪些特性? […]

龙生   08 Jun 2018
View Details

Windows 容器

什么是容器 容器是一种将应用程序包装到其自身隔离空间内的方法。 位于容器中的应用不了解该容器外存在的所有其他应用程序或进程。 应用程序成功运行所需的所有依赖项也存在于此容器内。 无论容器移动到何处,应用程序都将始终得到满足,因为应用程序与其运行所需的一切都已绑定在一起。 这就好像是一个厨房。 我们打包所有的电器和家具、锅碗瓢盆、洗洁精和毛巾。 这便是我们的容器 我们现在可以带着这个容器,将它放在任何喜欢的入住公寓中,厨房还会是这个厨房。 我们所需做的全部工作就是为它接通水电,然后我们便可以立即开始烹饪(因为我们拥有所有需要的器具!) 容器在很大程度上就像是这个厨房。 可以有不同类型的房间以及许多相同类型的房间。 重要的一点是容器与其所需的一切内容打包在一起。 在此处观看简短概述:基于 Windows 的容器:使用企业级控制的现代应用开发。 容器基础知识 容器是独立的、资源受控制的和可移植的运行时环境,在主机或虚拟机上运行。 在容器中运行的应用程序或进程与所有需要的依赖项和配置文件打包在一起;在它看来,容器之外似乎没有任何其他进程在运行。 容器的主机为容器预配一组资源,且容器只会使用这些资源。 在容器看来,除了已经为其提供的资源之外,不存在其他资源,因此它不能接触到可能已为相邻容器预配的资源。 在你开始创建和使用 Windows 容器时,以下关键概念将会很有用。 容器主机:使用 Windows 容器功能配置的物理或虚拟计算机系统。 容器主机将运行一个或多个 Windows 容器。 容器映像:在对容器文件系统或注册表进行修改时(如软件安装),将在沙盒中捕获这些修改。 在许多情况下,你可能希望捕获此状态,以便可以创建继承这些更改的新容器。 这就是映像的本质:一旦容器停止,你便可以放弃该沙盒,或者可以将其转换为新的容器映像。 例如,让我们想象你已从 Windows Server Core 操作系统映像部署一个容器。 然后你将 MySQL 安装到此容器中。 从此容器创建新映像将充当该容器的可部署版本。 此映像将只包含所做的更改 (MySQL),但是将充当容器操作系统映像之上的一个层。 沙盒:容器启动后,将在此“沙盒”层中捕获所有的写入操作,如文件系统修改、注册表修改或软件安装。 容器操作系统映像:从映像部署容器。 容器操作系统映像是可能组成容器的许多映像层中的第一层。 此映像提供操作系统环境。 容器操作系统映像是不可变的。 也就是说,不能对其进行修改。 容器存储库:每次创建容器映像时,容器映像及其依赖项都会存储在本地存储库中。 这些映像可以在容器主机上重复使用多次。 容器映像还可以存储在公共或私有注册表(如 DockerHub)中,以便可以在许多不同的容器主机上使用它们。 对于熟悉虚拟机的人员而言,容器可能具有令人难以置信的相似性。 容器在操作系统上运行、具有文件系统,并且可以通过网络访问,就像它是物理或虚拟计算机系统一样。 话虽如此,但容器背后的技术和概念与虚拟机有很大不同。 Microsoft Azure 专家 Mark Russinovich 有一篇精彩的博客文章详述了这些差异。 Windows 容器类型 Windows 容器包括两个不同的容器类型或运行时。 Windows Server 容器 – 通过进程和命名空间隔离技术提供应用程序隔离。 Windows Server 容器与容器主机和该主机上运行的所有容器共享内核。 这些容器不提供敌对安全边界,不应该用于隔离不受信任的代码。 由于共享内核空间,这些容器要求具有相同的内核版本和配置。 Hyper-V 隔离 – 通过在高度优化的虚拟机中运行每个容器,在由 Windows Server 容器提供的隔离上扩展。 在此配置中,容器主机的内核不与相同主机上的其他容器共享。 这些容器旨在托管敌对多租户,并且具有与虚拟机相同的安全保证。 由于这些容器与主机或主机上的其他容器不共享内核,它们可运行(与受支持的版本)采用不同版本和配置的内核 – 例如 Windows […]

龙生   08 Jun 2018
View Details

NET编程之事件总线(Event Bus)

1. 引言 事件总线这个概念对你来说可能很陌生,但提到观察者(发布-订阅)模式,你也许就很熟悉。事件总线是对发布-订阅模式的一种实现。它是一种集中式事件处理机制,允许不同的组件之间进行彼此通信而又不需要相互依赖,达到一种解耦的目的。 我们来看看事件总线的处理流程: 了解了事件总线的基本概念和处理流程,下面我们就来分析下如何去实现事件总线。 2.回归本质 在动手实现事件总线之前,我们还是要追本溯源,探索一下事件的本质和发布订阅模式的实现机制。 2.1.事件的本质 我们先来探讨一下事件的概念。都是读过书的,应该都还记得记叙文的六要素:时间、地点、人物、事件(起因、经过、结果)。 我们拿注册的案例,来解释一下。 用户输入用户名、邮箱、密码后,点击注册,输入无误校验通过后,注册成功并发送邮件给用户,要求用户进行邮箱验证激活。 这里面就涉及了两个主要事件: 1,注册事件:起因是用户点击了注册按钮,经过是输入校验,结果是是否注册成功。 2,发送邮件事件:起因是用户使用邮箱注册成功需要验证邮箱,经过是邮件发送,结果是邮件是否发送成功。 其实这六要素也适用于我们程序中事件的处理过程。开发过WinForm程序的都知道,我们在做UI设计的时候,从工具箱拖入一个注册按钮(btnRegister),双击它,VS就会自动帮我们生成如下代码: void btnRegister_Click(object sender, EventArgs e) { // 事件的处理 } 其中object sender指代发出事件的对象,这里也就是button对象;EventArgs e 事件参数,可以理解为对事件的描述 ,它们可以统称为事件源。其中的代码逻辑,就是对事件的处理。我们可以统称为事件处理。 说了这么多,无非是想透过现象看本质:事件是由事件源和事件处理组成。 2.2. 发布订阅模式 定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。 ——发布订阅模式 发布订阅模式主要有两个角色: 1,发布方(Publisher):也称为被观察者,当状态改变时负责通知所有订阅者。 2,订阅方(Subscriber):也称为观察者,订阅事件并对接收到的事件进行处理。 发布订阅模式有两种实现方式: 1,简单的实现方式:由Publisher维护一个订阅者列表,当状态改变时循环遍历列表通知订阅者。 2,委托的实现方式:由Publisher定义事件委托,Subscriber实现委托。 总的来说,发布订阅模式中有两个关键字,通知和更新。 被观察者状态改变通知观察者做出相应更新。 解决的是当对象改变时需要通知其他对象做出相应改变的问题。 如果画一个图来表示这个流程的画,图形应该是这样的: 3 实现发布订阅模式 相信通过上面的解释,对事件和发布订阅模式有了一个大概的印象。都说理论要与实践相结合,所以我们还是动动手指敲敲代码比较好。 我将以『观察者模式』来钓鱼这个例子为基础,通过重构的方式来完善一个更加通用的发布订阅模式。 先上代码: /// <summary > /// 鱼的品类枚举 /// </summary > public enum FishType { 鲫鱼, 鲤鱼, 黑鱼, 青鱼, 草鱼, 鲈鱼 } 钓鱼竿的实现: /// <summary > ///     鱼竿(被观察者) /// </summary > public class FishingRod { public delegate void FishingHandler(FishType type); //声明委托 public event FishingHandler FishingEvent; //声明事件 public void ThrowHook(FishingMan man) { Console.WriteLine("开始下钩!"); //用随机数模拟鱼咬钩,若随机数为偶数,则为鱼咬钩 if (new Random().Next() % 2 == 0) { var type = (FishType) new Random().Next(0, 5); Console.WriteLine("铃铛:叮叮叮,鱼儿咬钩了"); if (FishingEvent != null) FishingEvent(type); } } } 垂钓者: /// <summary > ///     垂钓者(观察者) /// </summary > public class FishingMan { public FishingMan(string name) { Name = name; } public string Name { get; set; } public int FishCount { get; set; } /// <summary > /// 垂钓者自然要有鱼竿啊 /// </summary > public FishingRod FishingRod { get; set; } public void Fishing() { this.FishingRod.ThrowHook(this); […]

龙生   07 Jun 2018
View Details

Autofac 组件、服务、自动装配 《第二篇》

一、组件 创建出来的对象需要从组件中来获取,组件的创建有如下4种(延续第一篇的Demo,仅仅变动所贴出的代码)方式: 1、类型创建RegisterType AutoFac能够通过反射检查一个类型,选择一个合适的构造函数,创造这个对象的实例。主要通过RegisterType<T>() 和 RegisterType(Type) 两个方法以这种方式建立。 ContainerBuilder使用 As() 方法将Component封装成了服务使用。

2、实例创建

单例 提供示例的方式,还有一个功能,就是不影响系统中原有的单例:

这种方法会确保系统中的单例实例最终转化为由容器托管的单例实例。 3、Lambda表达式创建 Lambda的方式也是Autofac通过反射的方式实现

4、程序集创建 程序集的创建主要通过RegisterAssemblyTypes()方法实现,Autofac会自动在程序集中查找匹配的类型用于创建实例。

5、泛型注册 泛型注册通过RegisterGeneric() 这个方法实现,在容易中可以创建出泛型的具体对象。

6、默认的注册 如果一个类型被多次注册,以最后注册的为准。通过使用PreserveExistingDefaults() 修饰符,可以指定某个注册为非默认值。

如果不使用PreserveExistingDefaults(),那么将输出“我是一个学生”。 二、服务 Autofac有三种典型的方式区分服务,同一个服务的不同实现可以由类型,名称和键区分。 1、类型 类型是描述服务的基本方法

并且上面的服务在自动装备中也有效

2、名字 服务可以进一步按名字识别。使用这种方式时,用 Named()注册方法代替As()以指定名字:

使用Name可以检索服务创建实例:

ResolveNamed()只是Resolve()的简单重载,指定名字的服务其实是指定键的服务的简单版本。 3、键 有Name的方式很方便,但是值支持字符串,但有时候我们可能需要通过其他类型作键。 例如,使用枚举作为key:

使用key注册服务,通过Keyed<T>()方法:

显式检索 使用key检索服务以创建实例,通过ResolveKeyd()方法:

ResolveKeyd()会导致容器被当做 Service Locator使用,这是不被推荐的。应该使用IIndex type替代。 IIndex索引 Autofac.Features.Indexed.IIndex<K,V>是Autofac自动实现的一个关联类型。component可以使用IIndex<K,V>作为参数的构造函数从基于键的服务中选择需要的实现。

IIndex中第一个泛型参数要跟注册时一致,在例子中是DeviceState枚举。其他两种注册方法没有这样的索引查找功能,这也是为什么设计者推荐Keyed注册的原因之一。 三、自动装配 从容器中的可用服务中选择一个构造函数来创造对象,这个过程叫做自动装配。这个过程是通过反射实现的,所以实际上容器创造对象的行为比较适合用在配置环境中。 1、选择构造函数 Autofac默认从容器中选择参数最多的构造函数。如果想要选择一个不同的构造函数,就需要在注册的时候就指定它。

这种写法将指定调用Worker(int)构造函数,如该构造函数不存在则报错。 2、额外的构造函数参数 有两种方式可以添加额外的构造函数参数,在注册的时候和在检索的时候。在使用自动装配实例的时候这两种都会用到。 注册时添加参数 使用WithParameters()方法在每一次创建对象的时候将组件和参数关联起来。

  在检索阶段添加参数 在Resolve()的时候提供的参数会覆盖所有名字相同的参数,在注册阶段提供的参数会覆盖容器中所有可能的服务。 3、自动装配 至今为止,自动装配最大的作用就是减少重复配置。许多相似的component无论在哪里注册,都可以通过扫描使用自动装配。

在需要的时候,依然可以创建指定的构造函数创建指定的类。

四、程序集扫描 1、扫描 Autofac可以使用约定在程序集中注册或者寻找组件。 Autofac可以根据用户指定的规则在程序集中注册一系列的类型,这种方法叫做convention-driven registration或者扫描。

[…]

龙生   04 Jun 2018
View Details

VS2017多项目模板

解决方案:

其中一个解决方案:

 

龙生   02 Jun 2018
View Details

模板参数

若要了解有关 Visual Studio 2017 RC 的最新文档,请参阅 Visual Studio 2017 RC 文档。 在对模板进行实例化时,您可以通过模板的参数,替换模板的关键部分的值,如类名和命名空间。 当用户在“新建项目”或“添加新项”对话框中单击“确定”时,这些参数将由后台运行的模板向导替换。 声明和启用模板参数 模板参数以 $parameter$ 格式进行声明。 例如: $safeprojectname$ $guid1$ $guid5$ 启用模板中的参数替换 在模板的 .vstemplate 文件中,定位到与要为其启用参数替换的项对应的 ProjectItem 元素。 将 ProjectItem 元素的 ReplaceParameters 特性设置为 true。 在项目项的代码文件中,在合适的位置包括参数。 例如,下面的参数指定用于文件中的命名空间的安全项目名称:

保留的模板参数 下表列出了可供所有模板使用的保留的模板参数。  说明 模板参数区分大小写。 Parameter 描述 clrversion 公共语言运行时 (CLR) 的当前版本。 GUID [1-10] 用于替换项目文件中的项目 GUID 的 GUID。 最多可以指定 10 个唯一的 GUID(例如,guid1))。 itemname 用户在添加新项对话框中提供的名称。 machinename 当前的计算机名称(例如,Computer01)。 projectname 用户在新建项目对话框中提供的名称。 registeredorganization HKLM\Software\Microsoft\Windows NT\CurrentVersion\RegisteredOrganization 中的注册表项值。 rootnamespace 当前项目的根命名空间。 此参数仅适用于项目模板。 safeitemname 用户在“添加新项”对话框中提供的名称,名称中移除了所有不安全的字符和空格。 safeprojectname 用户在“新建项目”对话框中提供的名称,名称中移除了所有不安全的字符和空格。 time 以 DD/MM/YYYY 00:00:00 格式表示的当前时间。 SpecificSolutionName 解决方案的名称。 当“创建解决方案的目录”被选中,SpecificSolutionName 具有解决方案的名称。 当“创建解决方案的目录”没有被选中,SpecificSolutionName是空。 userdomain 当前的用户域。 username 当前的用户名。 webnamespace 当前网站的名称。 在 Web 窗体模板中使用此参数以确保类名称是唯一的。 如果网站位于 Web 服务器的根目录下,则此模板参数将解析为 Web 服务器的根目录。 […]

龙生   02 Jun 2018
View Details

ProjectTemplateLink 元素(Visual Studio 模板)

若要了解有关 Visual Studio 2017 RC 的最新文档,请参阅 Visual Studio 2017 RC 文档。 指定多项目模板中一个项目的 .vstemplate 文件的路径。   语法

特性和元素 以下各部分描述了特性、子元素和父元素。 特性 特性 描述 ProjectName 可选特性。 指定多项目模板中每一个项目的名称。 新项目对话框中不能向单个项目分配名称。 CopyParameters 使主要组模板中的所有变量可复制到每个链接模板。 链接模板中的参数具有前缀 "$ext_*$"。 例如,如果在父组模板参数$projectname$具有值exampleproject1 则轮到,当模板链接获取又要执行,它将获取参数$ext_projectname$,这是一份$projectname$父组模板中的参数。 这使链接模板能够共享一些只能在父组模板中方便地创建的公用参数。 此特性为可选特性,未包含此特性时,它将自动默认为 false。 在 Visual Studio 2013 Update 2 中引入。 若要引用正确的产品版本,请参阅引用程序集提供的 Visual Studio 2013 SDK Update 2。 父元素 元素 描述 ProjectCollection 指定多项目模板的组织和内容。 SolutionFolder 对多项目模板中的项目进行分组。   文本值 需要一个文本值。 此文本指定模板的 .vstemplate 文件的路径。     多项目模板用作两个或多个项目的容器。 ProjectTemplateLink 元素用于指定模板中一个项目的 .vstemplate 文件的位置。 对于多项目模板中的每个项目,此模板的 .vstemplate 文件中都含有一个对应的 ProjectTemplateLink 元素。 有关多项目模板的详细信息,请参阅如何︰ 创建多项目模板。   此示例演示一个简单的多项目 .vstemplate 根文件。 在此示例中,模板包含两个项目:My Windows Application 和 My Class Library。ProjectName 元素的 ProjectTemplateLink 特性可为 Visual Studio 设置要分配给此项目的名称。 如果不存在 ProjectName 特性,则会使用 .vstemplate 文件的名称作为项目名称。

  from:https://msdn.microsoft.com/zh-cn/library/ms171398.aspx

龙生   02 Jun 2018
View Details
1 11 12 13 44