• [技术干货] .NET项目迁移到.NET Core操作指南
    这篇文章,汇集了大量优秀作者写的关于".NET迁移到.NET Core"资料文章以及微软官方教程文档。也是我在迁移公司框架项目到.NET Core和.NET Standard时遇到的问题,并将相关资料整理成这篇文章。记录如何一步一步把项目迁移到.NET Core。 为什么要从.NET迁移到.NET Core?.NET Core提供的特性开源协议.NET Core从属于.NET基金会,由微软进行官方支持。使用最宽松的MIT和Apache 2开源协议,文档协议遵循CC-BY。这将允许任何人任何组织和企业任意处置,包括使用,复制,修改,合并,发表,分发,再授权,或者销售。唯一的限制是,软件中必须包含上述版权和许可提示,后者协议将会除了为用户提供版权许可之外,还有专利许可,并且授权是免费,无排他性的(任何个人和企业都能获得授权)并且永久不可撤销,用户使用.NET Core完全不用担心收费问题,你可以很自由的部署在任何地方.轻量级、跨平台组件化、模块化、IOC+Nuget、中间件高性能统一了MVC和WebAPI编程模型比如:NET Core 中MVC 和Web API 直接或间接继承同一个基类 ControllerBase,提供可使用的API也一致化比如:旧NET时代,写全局filter需要针对MVC 和Web API 分别编写代码,但在ASP.NET Core,直接使用一套中间件代码即可可测试性微服务、容器化支持标准化 .NET API 规范- .NET STANDARD,整体架构如下图:.NET Core性能提升TechEmpower机构  TechEmpower机构会定期对各语言主流的web框架做性能测试  https://www.techempower.com/benchmarks/博客园博主、微软MVP – 杨晓东,做的 “Hello World”性能测试ASP.NET Core 1.1性能对比评测(ASP.NET,Python,Java,NodeJS)编号对比方系统环境宿主环境测试结果(QPS)1ASP.NET Core vs ASP.NET CoreWindowsKestrel vs IIS45.6k vs 15.2k2ASP.NET Core vs ASP.NETWindowsIIS vs IIS15.2k vs 18.2k3ASP.NET Core vs ASP.NETWindowsKestrel vs IIS45.6k vs 18.2k4ASP.NET Core vs Python DjangoLinuxKestrel vs uwsgi26.7k vs 1.57k5ASP.NET Core vs Java ServletLinuxKestrel vs Tomcat26.7k vs 18.3k6-1ASP.NET Core vs NodeJS ExpressLinuxKestrel vs self host26.7k vs 15.6k6-2ASP.NET Core vs NodeJS KoaLinuxKestrel vs self host26.7k vs 17.5性能测试工具:    微软出品:Benchmarks    https://github.com/aspnet/benchmarks其他阅读:   是什么优化让 .NET Core 2.0性能飙升?    .NET Core 3中的性能提升(译文)    Java(11,12) 与 .NET Core(2.2,3.0)的性能对比测试 .NET如何迁移到.NET Core?迁移工作量评估(API兼容性分析)度量.net framework 迁移到.net core的工作量可移植性分析工具:.NET Portability Analyzer 【Cli 版本】  【Visual Studio Extension 版本】  评估会给出类似如下报告:  .NET Standard Versions迁移方案制定微软官方《组织项目以支持 .NET Framework 和 .NET Core》文章中,有介绍两种迁移方案:方案一、将现有项目和 .NET Core 项目合并为单个项目(多目标框架)方案二、将现有项目和新的 .NET Core 项目分离(拷贝到新项目)   通过类名、命名空间,查询API的实现信息迁移过程中,有类库命名空间被调整,nuget归属包被调整,具体类库在.NET Core哪个版本中被实现也不是很清楚,通过下面两个查询助手,即可解决这些问题。1、查询命名空间、类库在哪个nuget package包中定义(第一次查询比较慢)2、查询 NET API 在各版本中实现结果图如下: 类库项目、应用项目如何选择框架类型.NetStandard;.netCore;FX(.NetFrameWork)之间引用关系在 .NET Standard 2.0中,我们使在 .NET Standard 库中通过一个兼容层去引用已有的 .NET Framework 的库成为可能。当然,这只对那些只使用了适用于 .NET Standard API 的 .NET Framework 库有效。FX引用.NetCore:不通过.NetStandard引用.NetCore:不通过 .NetCore引用FX:通过.NetCore引用.NetStandard:通过.NetStandard引用FX:通过FX引用.NetStandard:通过        ASP.NET Core可以在“.NET Framework 和 .NET Core”上运行,但ASP.NET Core 3.0 以及更高版本只能在 .NET Core 中运行。具体参见:  【译】介绍 .NET Standard -- 【原文】  关于.net core 和 .net fx相互引用的问题.NetStandard;.netCore;FX(.NetFrameWork)之间引用关系项目支持多目标框架支持多目标框架,并解决第三方库引用差异的问题(在 csproj 文件中指定包含条件)目标框架名称列表 (命名全小写)如何调试多目标框架类库?NET Standard/Core项目使用条件判断输出多版本xml注释文档多目标框架中共享代码方案【首选】.NET Standard,需要目标SDK支持对应的 .NET Standard 版本。共享项目。直接共享了源码,只要在目标项目中指定了条件编译符,那么源码便能针对各种不同的目标框架进行分别编译。[add as link]使用链接共享 Visual Studio 中的代码文件条件编译符号 (命名全大写)指令: #if #elif #else #endif (||、&&、!)因为目标框架提供的API不相同。故必要时可添加条件编译符号以便支持不同的运行时版本。微软有针对各个目标框架有预定义预处理器符号,vs编译时会自动识别到这些框架条件编译符号。.NET Framework 4.5 --> NET45.NET Framework 4.6 --> NET46.NET Framework 4.6.1 --> NET461.NET Standard 1.0 --> NETSTANDARD1_0.NET Standard 1.6 --> NETSTANDARD1_6.NETCOREAPP 2.0 --> NETCOREAPP2_0参考:#if指令文档如何将条件编译符号(DefineConstants)传递给m****uild 迁移到.NET Core,但只运行在windows平台上使用 Windows 兼容性包将代码移植到 .NET Core如何:将 Windows 窗体桌面应用程序移植到 .NET Core如何:将 WPF 桌面应用移植到 .NET Core 兼容.NET Core或.NET Standard API迁移HttpHandler与HttpModule到 ASP.NET Core 中间件.NET CORE 2.0 踩坑记录之ConfigurationManager.NET Core/Standard 2.0 编译时报“CS0579: Duplicate 'AssemblyFileVersionAttribute' attribute”错误ASP.NET Core开发之HttpContext.net core 使用JsonConvert替代JavaScriptSerializerASP.NET Core 中重复读取 Request.Body 的正确姿势JsonRequestBehavior在core中被移除的问题[ASP.NET Core]core中不会抛出AllowGet异常,对于DenyGet则使用[HttpPost]代替https://stackoverflow.com/questions/38578463/asp-net-core-the-name-jsonrequestbehavior-does-not-exist-in-the-current-conthttps://stackoverflow.com/questions/8464677/why-is-jsonrequestbehavior-needed?r=SearchResults获取ASP.NET Core中的Web根路径和内容根路径(移除的MapPath)为什么我的会话状态在ASP.NET Core中不工作了?由于ASP.NET Core 2.1中引入的Cookie同意和非必要cookie的GDPR功能引起。(GDPR,即General Data Protection Regulation,《通用数据保护条例》)在ASP.NET4.5和ASP.NET Core中共享cookies认证信息(加解密方式不一致问题)   .NET跨平台之旅:ASP.NET Core从传统ASP.NET的Cookie中读取用户登录信息   开源方案:[git]idunno.CookieSharingASP.NET Core如何获取客户端IP地址(被移除的ServerVariables对象)如何获取项目依赖的所有程序集   方案一:AppDomain.CurrentDomain.GetAssemblies(),此办法不能获取到所有依赖的程序集,因为.Net有延迟加载程序集机制   方案二:适用于传统ASP.NET项目,System.Web.Compilation.BuildManager.GetReferencedAssemblies();   方案三:适用于ASP.NET Core项目,DependencyContext.Default.CompileLibraries,具体代码参考下面var dlls = DependencyContext.Default.CompileLibraries    .SelectMany(x => x.ResolveReferencePaths())    .Distinct()    .Where(x => x.Contains(Directory.GetCurrentDirectory()))    .ToList();foreach (var item in dlls){    try    {        AssemblyLoadContext.Default.LoadFromAssemblyPath(item);    }    catch (System.IO.FileLoadException loadEx)    {    } // The Assembly has already been loaded.    catch (BadImageFormatException imgEx)    {    } // If a BadImageFormatException exception is thrown, the file is not an assembly.    catch (Exception ex)    {    }}参考:        AppDomain.CurrentDomain.GetAssemblies()        Is there an alternative for BuildManager.GetReferencedAssemblies() in ASP.NET Core?.NET Core 2.0迁移System.Runtime.Caching.NET Core 2.0升级到3.0实战方案  从.NET CORE2.2升级到3.0过程及遇到的一些问题迁移EF框架【微软官方】从 EF6 到 EF Core的迁移系列【微软官方】EF Core 版本升级迁移系列 修改为 ASP.NET Core 风格的应用  按照上面的方式修改API兼容性后,框架类库可以顺利迁移到.NET Core,编译通过,代码运行也正常。但是ASP.NET Core风格的应用,其写法也是有很多变化的。具体参考下面文档:将传统 ASP.NET 应用迁移到 .NET Core【微软官方】ASP.NET 迁移到 ASP.NET Core教程系列【微软官方】ASP.NET Core 版本升级迁移系列推荐阅读:  .NET Core 学习资料精选:入门  .NET Core 学习资料精选:进阶
  • [技术干货] 应用工具 .NET Portability Analyzer 分析迁移dotnet
    想让库支持多平台吗? 想要了解使 .NET Framework 应用程序在 .NET Core 上运行需要花费多大的精力? .NET 可移植性分析器是一种工具,可分析程序集并为应用程序或库提供有关缺失的 .NET API 的详细报告,以便在指定的目标 .NET 平台上实现可移植性。 可移植性分析器作为 Visual Studio Extension 提供,用于分析每个项目的一个程序集;也可以作为 ApiPort 控制台应用提供,用于按指定文件或目录分析程序集。将项目转换为面向 .NET Core 等新平台后,可以使用基于 Roslyn 的 API 分析器工具来识别引发 PlatformNotSupportedException 异常以及其他兼容性问题的 API。常用对象.NET Core:采用模块化设计,支持并行安装,面向跨平台方案。 可并行安装意味着无需破坏其他应用即可采用新的 .NET Core 版本。 如果目标是将应用移植到 .NET Core 以支持多个平台,则建议使用此对象。.NET Standard:包括所有 .NET 实现上提供的 .NET Standard API。 如果目标是使自己的库能够在所有 .NET 支持的平台上运行,则建议使用此对象。ASP.NET Core:在 .NET Core 基础上构建的现代 Web 框架。 如果目标是将 Web 应用移植到 .NET Core 以支持多个平台,则建议使用此对象。.NET Core + 平台扩展:除 Windows 兼容包之外,还包括 .NET Core API,后者提供了许多可用的 .NET Framework 技术。 这是推荐的对象,用于将 Windows 上的应用从 .NET Framework 移植到 .NET Core。.NET Standard + 平台扩展:除 Windows 兼容包之外,还包括 .NET Standard API,后者提供了许多可用的 .NET Framework 技术。 这是推荐的对象,用于将 Windows 上的库从 .NET Framework 移植到 .NET Core。如何使用 .NET 可移植性分析器若要开始在 Visual Studio 中使用 .NET 可移植性分析器,必须先从 Visual Studio Marketplace 下载扩展并进行安装。 它适用于 Visual Studio 2017 及更高版本。 可以通过 Visual Studio 中的“分析” > “可移植性分析器设置”对其进行配置,并选择目标平台,即选择 .NET 平台/版本,用于评估与当前程序集构建的平台/版本相比的可移植性差距 。还可以使用 ApiPort 控制台应用程序,可从 ApiPort 存储库进行下载。 可以使用 listTargets 命令选项以显示可用的目标列表,然后通过指定 -t 或 --target 命令选项来选择目标平台。解决方案范围视图分析包含多个项目的解决方案的一个很有用的步骤是,可视化依赖项以了解程序集中各个子集的依赖关系。 一般的建议是,从依赖项关系图中的叶节点开始,以自下而上的方式应用分析结果。要检索此项,可运行以下命令:控制台复制ApiPort.exe analyze -r DGML -f [directory or file]在 Visual Studio 中打开时,此结果如下所示:分析可移植性若要在 Visual Studio 中分析整个项目,请在“解决方案资源管理器”中右键单击该项目,然后选择“分析程序集可移植性” 。 也可以转到“分析”菜单,选择“分析程序集可移植性”。 在该位置选择项目的可执行文件或 DLL。还可以使用 ApiPort 控制台应用。键入以下命令即可分析当前目录:ApiPort.exe analyze -f .若要分析特定的 .dll 文件列表,请键入以下命令:ApiPort.exe analyze -f first.dll -f second.dll -f third.dll运行 ApiPort.exe -? 以获取更多帮助建议包含自己拥有的且要移植的所有相关 exe 和 dll 文件,并且排除应用所依赖的,但你既不拥有又无法移植的文件。 这将为你提供最相关的可移植性报表。查看和解释可移植性结果报表中仅显示目标平台不支持的 API。 在 Visual Studio 中运行分析后,你将看到弹出的 .NET 可移植性报表文件链接。 如果使用的是 ApiPort 控制台应用,.NET 可移植性报表将以指定的格式保存为文件。 默认位于当前目录中的 Excel 文件 (.xlsx) 中。可移植性摘要报表的“可移植性摘要”部分显示运行中包含的每个程序集的可移植性百分比。 在上述示例中,svcutil 应用中使用的 71.24% 的 .NET Framework API 在 .NET Core + Platform Extensions 中可用。 如果针对多个程序集运行 .NET 可移植性分析器工具,则每个程序集在“可移植性摘要”报表中都应有一行。详细信息报表的“详细信息”部分列出了任意选定目标平台缺少的 API。目标类型:该类型具有目标平台缺少的 API目标成员:目标平台缺少的方法程序集名称:缺少的 API 所在的 .NET Framework 程序集。每个选定的目标平台都是一列,例如“.NET Core”:“不支持”值表示此目标平台不支持 API。建议的更改:要进行更改的推荐 API 或技术。 对于许多 API,此字段当前为空或已过时。 由于 API 数量众多,在维护 API 最新状态方面,我们面临着巨大的挑战。 我们致力于提供备用解决方案,以便为客户提供有用的信息。缺少程序集可以在报表中找到“缺少程序集”部分。 此部分包含由你的经过分析的程序集引用的程序集列表(此列表未经过分析)。 如果它是你自己拥有的程序集,请将其包含在 API 可移植性分析器运行过程中,以便你可以获得详细的 API 级别可移植性报表。 如果它是第三方库,请检查是否存在支持目标平台的更新版本,并考虑转到较新的版本。 最终,此列表应该包含你的应用依赖的所有第三方程序集(其中具有支持目标平台的版本)。有关 .NET 可移植性分析器的详细信息,请访问 GitHub 文档和简要了解 .NET 可移植性分析器第 9 频道视频。
  • [技术干货] .NET应用迁移到.NET Core(调查案例)
    上一篇文章《.NET应用迁移到.NET Core(理论篇) 》讲述做.NET 应用迁移到.NET Core的一般方法。今天给大家展示一个真实的项目的调查案例,一个轻量级的.NET 工作流引擎移植到.NET Core平台的调查案例,你也可以参照这篇案例进行迁移前的项目调查工作。该调查问卷可以作为移植技术的一个指南,并且据此还可以提出其他一些问题。该问卷中的客户指的是一个要移植到.NET Core的内部或外部部门。平台相关的内容1、  你当前的应用程序开发平台是什么?该问题是关于开发待移植.NET应用程序的开发平台。这里不假设开发平台和应用程序部署的平台是相同的。这留在下一个问题中。Windows 7 + IIS 7.5 + .NET Framework 4.5 +Redis 2.4 + SQL Server 2008 R22、  该应用程序当前运行的平台是什么?移植工程师需要知道待移植的应用程序当前运行的平台。Windows 2008 R2 SP1 + IIS 7.5 + .NETFramework 4.5 + Redis 2.4 + SQL Server 2008 R23、  除了开发平台外,该应用程序是否还在其他平台上部署过?如果部署过,它运行的平台版本是什么?问此问题可以让你知道应用程序的可移植性,看它是否移植到其他平台上。不过有一点需要注意:即使应用程序曾移植到其他平台上,它的目标平台可能也是比较老的版本。没有在其他平台部署过。4、  描述应用程序使用的系统信息,以及需要的驱动程序在Linux平台上是否可用。确定Linux能够满足应用程序对平台的依赖。系统信息:.NET Framework 对应的Linux平台上有Mono 和 .NET Core两大平台Redis 已经是在Linux平台上运行Web服务器 IIS 对应Linux平台上有Jexus(Mono) 和 Apache/Nginx + Kestrel SQL Server 在Linux平台上存在但是还是预览版,可以迁移到MySQLEntity Framework 6.1 和 Entity Framework Core 本身就是跨平台的,支持在Linux平台上访问SQL Server ServiceStack.Redis 也是支持Mono和.NET CoreOwin 服务器在Linux 平台上有Jexus 支持和 .NET Core的支持ASP.NET Web API 2.2 Linux平台上有Mono 4.6 支持,也可以迁移到.NET CoreWindows服务可以迁移到Linux 的后台服务,可以Topshelf改造或者是迁移到.NET Core 控制台应用,使用Linux系统服务或者是Supervisorctl 运行站点使用的ASP.Net MVC 在Linux上Mono 4.6 支持,或者迁移到.NET Core 应用程序相关的内容1、  请详细描述应用程序及其结构。在这里,用户可以描述应用程序的结构,并尽可能地包括结构图。应用程序的所有组件都要描述。如果有的话,该问题也应该会让你知道应用程序运行的框架。大部分的.NET应用程序运行在产品相关的框架上,例如IIS 、windows 服务和WCF服务。也就是说,需要你处理.NET Core可能不支持的某个具体的框架。HRCommFlow应用包括2部分:对外的API服务和 Web站点。对外服务的API 服务使用ASP.NETWeb API ,使用Windows服务自宿主。使用的组件如下:应用框架组件备注ASP.NET Web APISystem.Web.HttpSystem.Web.Http.OwinMicrosoft.Owin.Host.HttpListenerEntityFramework访问SQL ServerNewtonsoft.JsonJsonServiceStack.Redis访问RedisTencent.OA.Framework访问组织机构信息ExpressionEvaluatorSystem.ServiceProcess Web 站点使用ASP.NET MVC 4 ,使用IIS 宿主应用框架组件备注ASP.NET MVCMicrosoft.AspNet.MvcMicrosoft.AspNet.RazorEntityFramework访问SQL ServerNewtonsoft.JsonJsonTencent.OA.Framework访问组织机构信息ExpressionEvaluatorSystem.ServiceProcess 2、  该应用程序有哪些不同组件?请给出各组件的名称和版本号。该问题让你细分应用程序的结构,把应用程序细分成不同的组件。也就是说,可以把整个移植工作分成多个独立的任务。组件名称版本号是否公开源代码System.Web.Http4.0.0.0是System.Web.Http.Owin5.2.3.0是Microsoft.Owin.Host.HttpListener3.0.0.0是EntityFramework6.1.3是Newtonsoft.Json6.0.8是ServiceStack.Redis3.9.71.0是Tencent.OA.Framework1.0.0.0是ExpressionEvaluator2.0.4.0是System.ServiceProcess4.0.0.0是Microsoft.AspNet.Mvc4.0.30506.0是Microsoft.AspNet.Razor2.0.30506.0是 3、  那些组件需要移植,那些不需要?请包含版本号。客户需要告诉你那些需要移植,那些不需要。组件名称版本号移植到Mono移植到.NET CoreSystem.Web.Http4.0.0.0不需要不需要System.Web.Http.Owin5.2.3.0不需要不需要Microsoft.Owin.Host.HttpListener3.0.0.0不需要不需要EntityFramework6.1.3不需要不需要Newtonsoft.Json6.0.8不需要不需要ServiceStack.Redis3.9.71.0不需要不需要Tencent.OA.Framework1.0.0.0需要需要ExpressionEvaluator2.0.4.0需要需要System.ServiceProcess4.0.0.0不需要不需要Microsoft.AspNet.Mvc4.0.30506.0不需要不需要Microsoft.AspNet.Razor2.0.30506.0不需要不需要 4、  待移植的应用百分之多少是用下列编程语言编写?JavaC#F#CC++汇编语言Visual BasicIronPython/IronRubyPowershell通过询问应用程序使用了什么语言及其所占的比重,来确定应用程序的复杂度。100% 使用C# 语言编写5、  粗略估计一下各语言所占的代码行数。这是对问题4的另外一种问法,从不同的角度提出问题,常常能找到互相矛盾的地方,这就需要公开讨论,从而能够把项目调查清楚。 代码数量大概是3500 行。 6、  对于.NET应用程序:使用了P/Invoke来链接特有的库了吗?请描述之。明确待移植的应用程序的复杂度。多数情况下,非100%纯.NET编写的应用程序,都需要平台相关的例程,这些例程只能用固有的语言来处理,例如C语言。请注意这些平台相关的代码,往往它需要花费较多的时间来移植。没有7、  应用程序用了操作系统内核模块了吗?如果有,请描述之。明确待移植的应用程序的复杂度。如果应用程序使用的操作系统内核模块和例程是不可移植的,就需要花费较多时间转换成目标平台上对应的例程。没有8、  该应用程序是2D/3D的图形应用程序吗?请描述之。明确待移植的应用程序的复杂度。确认.NET Core上存在兼容的图形工具和开发工具,无论是系统默认提供的或者是第三方发行商提供的。没有9、  应用程序使用了消息队列、共享内存、信号或者信号量吗?请描述之。上述内容大部分能够方便的移植到.NET Core上。需要确认移植到.NET Core后,能够使原来期望的行为。没有10、             应用程序或其中的组件,是多线程的吗?如果是,使用的是那种线程库?应用程序依赖开发平台特有的线程属性吗?Linux支持多种线程库,但是现在以及将来的Linux发行版中,符合标准的线程库是NPTL(Native Posix Threads Library)实现。组件没有多线程,也没有依赖开发平台特有的线程属性。11、             应用程序的某些操作提前假设某种特定的字节顺序吗?这在移植过程会成为问题吗?该问题是关于应用程序的“大小端”(Littleendian,Big endian)问题。大部分.NET移植到.NET Core的目标平台都是Intel平台,该平台是小端的。也有可能要把.NET程序移植到RISC 类的大端平台。假设具体的大小端代码是不可移植的,并且如果移植不正确会导致不易察觉的错误。更糟糕的是,这些错误在移植时不会暴露出来,只会在系统测试的时候会突然出现问题,并且很难找到问题的根源。没有假设字节顺序问题,.NET Framework帮助我们解决这个问题12、             开发平台使用的是那种编译器版本?C# (什么版本?)VB.NET(什么版本?)F#(什么版本?)平台特有编译器(Visual C++)其他(请列出)明确待移植的应用程序的复杂度。如果待移植的应用程序用的是C#/VB.NET或者F#编译器,则移植到Linux上会简单一些,因为.NET Core和.NET使用相同的编译器。如果用了windows平台特有编译器编译的应用程序,C++应用程序比C程序较难移植,应用程序可能使用了C++特性,例如模板。因为C++标准在不同厂商的编译器上实现不同,移植这种类型的代码比简单的C/C++代码要花费更多的时间。使用C# 编写的应用程序,.NET Core和.NET使用相同的编译器,Mono也是兼容的编译器。13、 除了开发环境,应用程序还依赖其他的调试工具吗?例如内存泄漏调试器、性能分析工具、异常处理等。这又回到了调查和分析依赖关系。Linux上可能有,也可能没有所需的第三方工具,这需要调查。谁提供许可?谁负责获取这些工具?如果需要第三方支持,谁来提供支持?没有依赖其他的调试工具。14、 该应用程序是基于Socket的吗?如果是,它使用了RPC吗?请描述之。虽然Linux支持标准的socket和RPC语义,但该问题的目的是确认程序的可移植性,比如.NET使用了WCF的RPC,.NET Core仅支持WCF的客户端访问,对于系统移植就很困难。问该问题可以搞清楚客户是否在应用程序里实现了不可移植的结构。该问题也可以引出其他问题,例如在测试阶段需要怎么样的配置。没有使用RPC,使用的是HTTP Web API,依赖的组件Tencent.OA.Framework 依赖于WCF的客户端访问,需要移植到HTTP Web API 接口访问。15、应用程序使用了第三方软件组件吗(数据库工具、应用程序服务器或其他中间件)?如果是,使用了哪些组件?每一个第三方软件组件都会增加移植的复杂度。如果使用了任何第三方组件,都需要询问试了该组件的那个版本以及.NET Core上是否存在对应版本。第三方组件可能需要额外的时间去学习,甚至是配置或编译。应用程序使用了第三方组件,组件名称版本号 Mono是否存在对应版本.NET Core是否存在对应版本System.Web.Http4.0.0.0存在存在System.Web.Http.Owin5.2.3.0存在不存在Microsoft.Owin.Host.HttpListener3.0.0.0存在不存在EntityFramework6.1.3存在存在Newtonsoft.Json6.0.8存在存在ServiceStack.Redis3.9.71.0存在存在Tencent.OA.Framework1.0.0.0存在不存在ExpressionEvaluator2.0.4.0存在不存在System.ServiceProcess4.0.0.0存在存在Microsoft.AspNet.Mvc4.0.30506.0存在存在Microsoft.AspNet.Razor2.0.30506.0存在存在 16、             应用程序时如何交付和安装的?使用标准的打包工具吗?安装脚本也需要移植吗?Linux上一个标准的打包工具是RPM。RPM会在其他章节讲述。明确客户是否需要移植应用程序打包部分的内容。使用XPlat 模式,没有使用打包工具,直接拷贝,部署运行。17、             应用程序或组件是64位的吗?有组件需要移植成64位的吗?随着64位平台和操作系统的普及,该问题是要知道应用程序需要运行在什么体系结构的平台上。通过现代的编译器,大部分32为应用程序都可以轻松移植到64位环境上。需要考虑的一点就是移植和调试可能需要较长的时间。应用程序都是64位的,不存在组件需要移植成64位。数据库内容1、  应用程序当前支持什么数据库?请包括版本号。现在几乎所有的企业应用程序都需要后台数据库。确认应用程序所需的数据库在Linux上可用非常重要。数据库产品以及版本之间的差别会导致增加很多移植工作。应用程序支持的SQLServer 2008 R2,目前在Linux上处于预览版,需要移植到MySQL。2、  移植后的应用程序期望运行在什么数据库上?除了问题1外,客户希望移植后的应用程序运行在Linux平台的什么数据库上?希望移植后应用程序运行在Linux的MySQL 5.6上。3、  应用程序使用了非关系数据库或私有数据库吗?现在还有很多应用程序使用NoSQL数据库,幸运的是大部分NoSQL数据库都运行在Linux上。任何私有数据库都需要移植到Linux上。确认运行数据库的代码在Linux上可用,这也是调查阶段工作的一部分。应用程序使用了NoSQL 数据库Redis,Redis在Linux上运行良好。4、  应用程序是如何与数据库通信的?编程语言(例如C#,VB.NET等)数据库接口(例如ODBC,ADO.NET,Entity Framework)确认所用的编程语言或接口在Linux上可用,确认是否由第三方厂商提供。应用程序使用了Entity Framework 访问SQL Server,微软官方提供。5、  应用程序需要使用扩展的数据类型吗(XML、audio,binary、video)?这个问题主要用来评估移植小组需要具备的技能。应用程序使用Json 数据类型。项目移植时间进度内容1、  应用程序在目标平台上的正式可用日期是那天?该问题是要明确在制定移植进度计划时,是否有商业目标需要考虑。需要在2017年春节前上线运营。 2、  应用程序在目标平台上的移植工作已经开始了吗?这可以帮助评估在正式开始之前发现的复杂度问题。没有开始。 3、  估计得移植复杂度是什么(低、中还是高)?需要仔细分析对该问题的回答。现在很可能有一些新的因素在以前的移植经历中没有完全认识到。 移植复杂度适中,都是用C#语言编写的应用组件,需要移植的第三方组件也比较少,而且都有源代码。 4、  在确定复杂度级别时,考虑了什么因素?以前移植工作的任何信息都需要评估,并且与将来的Linux平台移植工作进行对比。 5、  该应用程序曾移植到其他平台上吗?用了多长时间?需要多少资源?遇到过什么问题?该问题试图把以前的移植工作和.NETCore移植进行比较。这只有在移植工程师的技术领导同时具有Windows平台和Linux平台移植经验的情况下,才会有用。没有 6、  你是怎样粗略估计项目移植时间和所需资源的?应用程序或某些部分可能曾移植到其他平台上,知道向那些平台移植所花的时间会有些帮助。从那些移植过程得出的经验和教训会派上用场。吸取这些教训可以帮助你避免向.NET Core移植时重蹈覆辙。  测试相关的内容1、  请描述接收测试的环境配置。服务器配置用途环境tLinux 2.2/CentOS 7.2API 服务器Mono 4.6/Jexus/.NET Core 1.1/NginxtLinux 2.2/CentOS 7.2数据库服务器MySql 5.6+tLinux 2.2/CentOS 7.2Redis服务器Redis 3.2Windows Server 2008 R2原API服务器/数据库服务器SQL Server 2008R2 2、  单元测试需要什么样的网络和数据库配置? 3、  移植测试需要多少时间和资源? 4、  是否已经建立了测试脚本和性能度量标准? 5、  需要运行一些基准测试来进行比较吗? 6、  性能数据在当前平台上可用吗? 7、  最后执行性能测试是什么时间? 所有测试相关的问题都适用于软件程序在Linux平台上的测试。问这些问题还可以引出其他一些与移植测试脚本和测试工具有关的问题,而这些可能会增加整个项目的风险和时间。要重点关注客户对问题1的回答。问题1和接收标准有关,这些标准需要各方在移植开始之前都同意。一个接收标准的例子是:模块A和B应该通过测试用例c和d,并且没有错误。当达到测试标准后,移植可以说是完成了,正式的QA测试接着就可以开始了。项目移植的执行内容1、  根据你希望的情况,请选择下面的一项或多项:必要的话,将会给移植工程师提供一些技术帮助。客户负责获取第三方工具许可和技术支持。其他(请描述)。可以在这里增加你认为需要客户考虑的其他事项。有些问题可能是关于员工培训或测试应用程序等。 2、  项目需要什么硬件?该问题是要确认是否会用到现有的硬件或额外的硬件,以用于移植、测试、培训,以及必要的支持等。 尽管上述问卷已经比较全面,但是它不应该是调查所依赖的唯一基础。调查还应该包括对应用程序源代码的实际检查。软件程序的文档也需要检查,以便用户能够从中了解到需要的应用程序信息。
  • [技术干货] .NET应用迁移到.NET Core(方法论)
    把一个运行在某个操作系统和硬件结构上的软件,在另一个操作系统和硬件结构上重新编译(包括一些必要的修改),以便在新的平台上运行,这一过程叫做应用程序移植。有些情况下,把应用程序从一个平台移植到另一个平台非常简单直接,仅需要重新编译并进行一些验证测试即可。但是有些情况下,移植程序并不是那么容易。本篇是在应用程序移植方面对当前项目管理的一个补充,关于如何使用正规化的需求管理过程、如何更好的与软件开发人员交流,以及如何进行项目管理,今天的项目经理们都已经非常熟悉了,但是,软件开发和软件移植毕竟并不完全相同,这也就是本章要讲述的内容。本篇重点讲述软件移植的详细过程和技术风险,并列出一些实现高质量应用程序一致的习惯和方法。软件程序商业过程    在开始一个移植项目之前,很重要的一点就是要搞清楚在这个应用程序的生命周期中那些商业过程会受到影响。那些受到影响的商业过程必须进行修改,以适应移植后的应用程序,因为需要支持新的平台、新的测试环境、新的工具、新的文档,最重要的是,是需要支持新的客户并建立客户关系。      在应用程序的生命周期中,可能会影响到商业过程的三个主要领域是开发和测试、客户支持,以及应用程序发布:开发和测试。在开发和测试部门,必须在以下方面对开发测试人员进行Linux/Windows技能测试:应用程序编程接口(API)的区别、开发工具、调试功能根据、性能工具,以及待移植的应用程序需要的第三方软件。客户支持。在客户支持部门,必须在以下方面对支持人员进行培训:Linux/Windows系统管理、移植后的应用程序需要的第三方软件、安装和管理方法、Linux/Windows环境下的包管理工具、调试工具和方法,以及所需要的其他内容。应用程序发布。在应用程序发布部门,必须在Linux/Windows整体特性和知识方面对销售人员和技术顾问进行培训。对软件发布渠道人员,必须对其进行培训,使其成为Linux/Windows软件程序的培训者。从客户的角度看,他们也希望获取Linux/Windows集成方面的知识,一并能够把Linux/Windows和他们已有的IT系统集成在一起。.NET应用移植应用程序到.NETCore平台,也就意味着修改可能受到新移植的应用程序影响的商业组织过程。应该在真正的移植开始之前,认真考虑这三个主要的方面,并将他们包含在整个移植项目过程中。移植过程    参与移植项目的开发人员在移植任何项目时都可以遵循类似的步骤。这些步骤包括:调查、分析、移植及测试。过程中的每一步都是后一步的基础。每一步都做好,后续的步骤也就会很容易完成。调查    ”调查“这一步主要是项目经理召集移植专家(在应用程序方面比较有经验,并且对开源平台、目标平台及应用程序使用的第三方产品比较了解的软件开发人员)和某一领域内的专家一起来确定待移植的应用程序所依赖的产品、开发和测试环境等。在调查阶段要明确的几个关键内容包括:产品/软件依赖关系、开发环境组件、编译环境组件和测试环境组件。产品/软件依赖关系。确定待移植的应用程序所依赖的产品,也就是要确定该应用程序使用那个版本的数据库、中间件以及第三方类库等。知道了所依赖的产品和版本,移植专家就可以估计在.NET Core平台上是否有这些产品和版本。开发环境组件。确定开发环境包括确定待移植的应用程序时用哪种编程语言编写的。使用较新的编程语言(例如C#)编写的应用程序比较容易移植,但是使用C/C++语言编写的应用程序需要花费较多的时间来分析和移植。编译环境组件。确定编译环境包括确定需要的编译工具是否在Linux/Windows上可用。对于在源平台上使用的平台相关的编译和链接标志必须进行调查,以确定在Linux/Windows上是否存在对应的标志。有些编译环境可能依赖于原平台,这可能要花费较多的功夫才能移植到Linux上。测试环境组件。确定移植后的应用程序所使用的测试环境,会引入一些测试人员应该关注的问题。通常情况下,移植工程师只对他们移植的部分做单元测试,然后就把程序交给测试组来做更完整的验证和系统测试。但是,谁是测试组呢?多数情况下,“调查”这一步也会明确一些项目开始后可能遇到的风险。在调查阶段可以明确的风险如下:需要的数据库、中间件和依赖的第三方程序集在.NET Core上不可用。应用程序包括一些需要转换成Linux汇编指令的汇编例程。应用程序使用了源平台特有的API或编程模型。这也包括编写程序时对字母大小写和字节序的假设。应用程序时按照.NET的某个版本编写的,而该标准的实现又依赖于原平台上特有的编译器。测试环境需要复杂的客户端/服务器架构。开发环境需用第三方工具,而该工具需要移植到.NET Core上。应用程序的发布或安装需要源平台的特有的工具。“调查”这一步需要关注每一个新信息,这些信息可以通过问一些问题得到,例如关于文档、打包、性能调整等的问题。分析     “分析“这一步需要从两个角度来考虑:项目管理和移植。从项目管理的角度看,分析就是要评估在前一个步骤中确定的各种移植问题和风险,以及它们会对项目移植产生怎么样的影响。”分析“这一步要制定项目计划,包括确定项目的范围和目标、创建工作进度计划、获取资源,以及分配项目角色。   确定项目的范围和目标也定义了项目经理和组员的职责范围和责任。项目范围指的是项目要完成的一系列工作。例如,像“应用程序ABC的模块A需要移植到平台B上,并在B上测试”,这样的简单陈述就是一个很好的定义项目范围的例子。   项目范围定义以后,移植工作的具体任务也就是可以定义了,这就产生了一个工作详细分类的进度表。该进度表可以帮助确定哪些工作需要做,以及这些工作是顺序做还是可以并行来做。另外,该进度表还列出了所需要的资源。一个完整的进度表可以通过定义项目任务和所需的资源得到。   从移植的角度看,“分析”这一步就是移植工程师详细地分析应用程序的结构。移植工程师要确定应用程序所使用的API和系统调用,并且评估应用程序使用的动态链接和装载、网络、线程等。分析得到这些信息反馈给项目经理,项目经理据此确定更为详细的任务,并制定出更为准确的计划。移植    “移植“这一步就是移植工程师开始执行分配给他们的具体工作。根据前一步得出的工作细目表,移植工程师可能只能串行的工作。这主要是因为待移植的程序可能是紧耦合的。也就是说,应用程序的一个模块高度依赖于其他模块,只有那些被依赖的模块移植完成后,这些模块才能开始移植。一个典型的例子就是编译环境的移植。如果原来的编译环境是设计成一次编译整个应用程序,那么必须在任何移植工作之前,把各模块所依赖的通用配置文件修改完毕。    如果移植工作相互之间没有关联,则移植可以并行进行。松耦合模块的移植可以分开来让不同的工程师同时进行。一个典型的例子就是共享库的移植,这样的共享库相互之间没有影响,可以各自独立编译,并且只是供其它模块编译链接使用。确定哪些工作可以并行进行是很重要的,并且这一工作应该是在分析阶段完成。     在.NET Core上编译代码的工作包括确定并消除代码对体系结构的依赖,以及非标准的编程习惯,包括检查代码并使用可移植的数据结构或编码标准。有经验和质量意识较强的移植工程师会纠正编译错误的同时检查后者。      移植工作也包括移植编译环境到Linux/Windows平台。该工作应该在调查阶段明确下来。有些编译环境是可移植的,但有些并不是。确认编译环境不会导致潜在的问题是很容易被忽略的工作,需要非常仔细的调查和分析。      应用程序移植完成以后(也就是说,在.NET Core上编译完成了),移植工程师需要对移植的应用程序进行单元测试。单元测试可以很简单,例如可以简单的运行程序,看是否产生运行时错误,如果产生运行时错误,就需要在把应用程序交付给测试组以前修改完成这些错误。如何,测试组会对程序进行更完全的测试。测试      在测试过程中,指定的测试人员会对移植后的应用程序运行一些测试用例,这些测试用例都有不同的测试目的,从仅仅运行应用程序的简单测试到测试应用程序在.NET Core平台上是否足够健壮的压力测试。在目标平台上对应用程序进行的压力测试,可以发现那些除体系结构依赖和坏的编码习惯之外的问题。大部分应用程序,尤其是多线程程序,在不同平台上进行压力测试时,往往会表现出不同的行为,部分原因是因为不同的操作系统实现,尤其是不同的线程的实现。如果在测试过程中发现问题,移植工程师就应该去调试和解决这些问题。     有些应用程序移植也包括移植一套测试工具来测试该应用程序。移植测试工具也是应该在调查和测试阶段确定的一个任务。多数情况下,测试人员往往需要接受一些对应用程序的培训,才能测试该应用程序。学习应用程序是一个与移植工作完全独立的任务,可以与移植任务并行进行。测试发现问题后,需要解决这些问题并重新编译应用程序;然后重新测试该问题,直到应用程序通过所有的测试用例。支持     移植工作完成后,开发阶段就算结束了,支持阶段也就随之开始。一些移植工程师会留下来帮助回答客户可能提出一些一直相关的问题。另外,开发人员也应该培训客户怎样在Linux/Windows平台上配置和运行应用程序。在移植结束后,支持阶段一般需要持续60到90天。在这期间,针对新移植到.NET Core的应用程序,移植工程师对技术支持人员和销售人员进行培训,并回答他们提出的问题。在培训完成以后,移植工程师的工作就算完成了。 定义项目范围和目标定义项目范围就是定义清楚项目的结束点和边界,以及项目经理和项目成员的责任。定义清晰的项目范围可以确保该项目的所有相关者(参与项目或者受项目影响的人员或组织,如项目组、架构师、测试人员、客户或赞助商、合作部门等)都明确该项目的目标。清晰的项目目标或需求可以让人更好地理解项目范围。在移植过程的分析阶段,客户的目标和需求被收集上来,然后被细分成各个结构,并最终定义成项目的交付物。项目的目标和需求是定义项目范围的起点。所有的项目目标都确定以后,项目的范围也就变得更加明确了。定义项目范围的一种方法是,列出项目要包含和不包含的目标。从客户收集需求列表是个很好的开始方法。需求收集上来后,项目经理和技术领导详细的检查需求列表。如果对某些需求有疑问,应该把它们列到不被包含的目标列表中,至少最初时应该这样做。然后客户再次检查该列表,并对有异议的地方进行纠正。最后,知道所有人员都认为该列表已经正确表述了项目应该包含的所有目标。需要再次强调的是,该列表需要足够详细,以便能够列出那些要包含在项目中,那些不要。的确,对超出项目范围的需求列出详细说明也是很重要的。对定义项目范围不能提供足够信息的目标,随着项目发布日期的临近,会逐渐成为争论的焦点。例如各个部分移植工作怎样交付给移植小组---是多次迭代还是一次性交付?每次交付时作为一个阶段,还是有一些更小的工作包含在该阶段中?在一个完整的项目中有多少个迭代?该列表不仅定义了项目本身,也列出了该项目的所有相关干系人所期望的结果。下面列出创建项目目标列表时需要遵循的一些基本原则:1、 尽可能详细定义项目范围。2、 确认项目的所有相关干系人都同意该项目范围。3、 在“不包含/不在范围内”列表中列出未解决的内容,直到全部解决。定义项目目标的一部分工作是列出项目的接收和完成标准。关于项目的完成标准,所有的项目干系人必须达成一致意见。项目完成可能是指在Linux/Windows平台上通过了百分之多少的系统测试,或者是通过了系统性能所设定的某个性能标准—也就是说,项目目标是运行一组具体的测试用例或者性能分析。不管项目完成的标准是怎样定义的,如果可能的话,所有的项目干系人在移植开始之前都必须理解并且同意这些标准。任何在移植过程中对标准的修改早替代现有标准前都必须与所有相关干系人交流协商并得到批准。很多移植项目超出预算或未能按时完成,主要是因为没有很好地管理移植过程中可能遇到的风险。风险是在估计进度和资源时要考虑的一个重要因素。在应用程序移植项目中,这些风险来自与移植相关的不同方面,主要包括下面几种:移植工程师的技能水平和移植经验。使用的编译器。使用的编程语言。第三方软件和中间件的可用性。编译环境和工具。平台依赖的结构。平台和硬件依赖的代码。需要搭建的测试环境。用户界面需求。依赖于要移植的具体应用程序,以上各个方面的每一个都可能给移植项目带来不同的复杂度和风险。评估这些复杂度和风险的级别,可以帮助你确定它们是不是可管理的。技能水平和移植经验    应用程序移植和软件开发最明显的区别就是编程人员所掌握的技能。虽然软件开发人员往往是某一领域内比较专业的人员,但是要做软件移植的开发人员却需要更宽广的知识和技能。一个应用程序开发人员可以是Windows开发环境上的.NET专家,或者是Windows操作系统上SQL Server的数据库专业开发人员;但是,从事代码移植工作的工程师却通常需要时两个或者更多操作系统、编程语言、编译器、调试器、数据库、中间件或最新的基于网页的技术方面的专家。他们还需要知道怎样安装和配置第三方数据库或中间件。      应用程序开发人员需要的往往是专才,而移植工程师则多是通才。应用程序开发人员可以为一个软件工作18个月,但是移植工程师在一个项目上往往只需要工作3~6个月,并且在上一个项目完成以后,即可投入下一个新的移植项目中。为一个移植项目找到完全适合的移植工程师有时候是很困难的,从老的技术移植到新的技术上时尤其如此。编译器       在Windows平台上使用的编译器和编译器框架,与Linux平台上使用的有很大不同。如果在Windows平台和Linux平台上使用的是相同的编译器,移植工作将会变得容易一些,例如在两个平台上都是用的是GNU编译器,除了-g和-c标志外,不同的编译器使用的编译器标志可能大不相同,尤其是应用程序使用C++语言的时候。     另外一个需要考虑的事情是编译器的版本。要移植的代码可能是几年前使用老版本的编译器编译的,这些代码可能使用了与新的编译器不同的语法,这就使得在不同的编译器上移植程序比较困难,因为这些编译器可能支持也可能不支持老的标准,即使新的编译器支持老的标准,不同编译器对这些标准的支持方式也可能不太相同。.NET Core项目的C# 编译器的实现非常完整,和.NET编译器实现遵循同样的ECMA标准的“Roslyn”新编译器,大大降低了移植.NET项目的难度。第三方软件和中间件的可用性    当待移植的应用程序使用了第三方软件或中间件时,移植的复杂度会随之增加,尤其是在目标平台上没有这些第三方产品时,移植的难度会更大。可能会出现在Linux 平台上没有可用的第三方产品。在过去的几年中,一些中间件厂商,例如IBM,Oracle等都把他们的中间件产品移植到了Linux上。他们花了一些功夫,使那些已经使用或者准备使用Linux作为企业平台的公司在Linux上可以使用它们的中间件产品。这也是为什么越来越多的公司愿意把应用程序从Windows移植到Linux上的部分原因。 编译环境和工具      编译环境越简单,理解如何编译源代码所需的时间也就越少。需要多遍编译的编译环境往往都很复杂。在这些多遍编译中,使用不同的编译器标志来编译目标文件,以便解决模块间的互相依赖。第一遍编译一些模块,第二遍可能会编译更多的模块,但是第二次编译使用了前面的编译的结果,以此类推,直到整个编译过程结束。有时候,根据一些非标准的配置文件,编译脚本会调用其他脚本来自动生成一些文件。这些文件的大部分可以和待移植的文件一样看待,但是事实上,这些脚本工具和配置文件才是要移植到目标平台上的内容、这种类型的工具往往会在评估和分析时漏掉了,进而可能会破坏已经制定的进度计划。    源代码控制是另一个必须考虑的。在Linux环境下,Subversion和Git是应用最广泛的源代码控制工具,在一个移植项目中,如果有多个工程师同时来移植相同的模块,那么就需要进行源代码控制。平台依赖的结构     当从基于x86的Windows平台移植到基于RISC/ARM结构的Linux平台上时,需要检查应用程序对字节序的依赖和字母大小写敏感,例如,为了计算或数据操作而是用了字节交换的应用程序。在没有正确修改字节交换逻辑的情况下,调试问题将变得非常麻烦,因为很难找到数据在哪里出了问题,这主要是因为问题的根源通常是在发生问题的代码之前很远的地方。在调查和分析阶段,一定要找出平台依赖的结构。平台/硬件依赖的代码   需要内核扩展和设备驱动程序支持的应用程序时最难移植的。所有平台的内核API都不遵循任何标准。因此,API调用、参数个数,甚至是怎样把这些扩展装载到内核,在各个平台上都是不同的。多数情况下,都需要在Linux上开发新的代码。不过有一件事可以肯定,内核代码通常是使用C语言或者平台相关的汇编语言编写的。 搭建测试环境     移植工作完成以后,如果项目的范围还包括系统测试和验证,测试代码所需要的设备可能也会增加移植的复杂度。如果应用程序需要在复杂的集群或网络环境中测试,设置环境和调配资源也会增加项目的时间。      测试也可能包括性能测试。通常,性能测试都需要运行最大配置,以便检测应用程序在满负载下的运行情况。     移植应用程序测试工具的工作也需要包含在移植进度计划中。需要对包括软件测试和专用硬件配置的测试工具进行评估,以确定其需要多长时间进行移植和配置。 用户界面需求    移植用户界面可能很简单,也可能很复杂。基于ASP.NET的用户界面比较容易移植,基于WPF/WinForm技术的用户界面移植移植也简单,.NET Core已经支持WPF/WinForm,但是局限于Windows平台,WinForm 通过Mono可以实现跨平台。 下面的表总结了需要考虑的各个方面,各个方面都根据其使用的技术列出了难、中、易。 内容容易中等复杂度高复杂度编译器/编程语言C#、F#使用的语言在.NET Core上支持有限待移植代码的是C++/CLI使用第三方产品或中间件None.NET Core上支持的和可用的Linux上不支持的;使用了C++编写的第三方工具编译环境和工具MsBuild 脚本MsBuild 脚本和编译脚本组合在一起平台/硬件依赖的代码非平台/硬件依赖的代码平台/硬件依赖的代码来自第三方产品,而且已经移植到了.NET Core使用了内核扩展及设备驱动代码测试环境及其搭建独立的客户端/服务器设置网络、高可用行,集群;需要外部设备来测试,如打印机、光纤连接通道磁盘等用户界面ASP.NET MVCASP.NET WebForm不可移植的用户界面,例如WPF      经验表明,整个移植项目所需的实际工作量,在移植项目开始的前两三周,就可以评估出来。这段时间是待移植代码刚交付给移植项目组,而且移植工程师刚开始熟悉该软件程序,也可能是移植工程师刚开始移植该软件程序。他们开始分解应用程序组件,并搭建最初的编译环境。在最初的两三周内,移植工程师会完成编译环境的配置,并开始编译一些模块。     过了最初的两三周后,最好重新检查原先评估的进度计划,并根据刚得到的实际经验决定是否对计划进行调整。创建项目移植进度表      创建移植进度表时要考虑所有可能的风险,包括技术和商业相关的问题。技术方面,需要考虑资源和硬件是否可用、第三方的支持,以及Windows/Linux方面的经验等;商业方面,需要考虑部门重组,位置调整(如改变办公地点),发布给客户的日期,以及商业目标的改变等,这些都会影响到整个移植进度。     上面这些技术和商业方面的问题,形成了移植项目对外部的依赖关系,而这些依赖又不是移植项目可以控制的。因此,建议仔细考虑每一个外部问题,以减少项目的风险。      创建移植项目的进度计划和做开发项目类似。   在移植过程中每次进入下一个步骤时,项目组都可以根据实际的进度和资源对项目重新估计。本质上讲,每一个阶段的结束,不仅仅是移植过程中的一个里程碑,也应该是重新检查先前估计得一个检查点。 从商业角度看移植过程      移植过程不仅仅是移植软件程序,移植后的应用程序最终还需要必要的商业支持,以成为一个完整的,成功的商业项目。在移植工作进行的同时,项目的相关干系人还需要准备对该应用程序提供支持的部门。客户支持和软件发布等部门还需要介绍应用程序在Linux上如何运行的支持和培训。      对客户支持和软件发布人员进行必要的Linux培训,应该在项目目标中列为高优先级。与任何新产品一样,用户和系统管理员每次都会对新的发布提出很多问题。因此,也需要回答Linux系统管理的问题。我们的经验表明,刚移植到新的平台上的应用程序会产生很多关于系统管理以及如何使用新操作系统的问题,在支持热线接到的电话中,有五分之三的问题都是此类。      随着系统管理和安装问题的解决,关于应用程序的技术问题会逐步显现。支持部门需要访问测试机器来复现客户的问题。这些机器可能是开发或移植机器,依赖于应用程序和需要调试解决的实际问题。     从项目的整体来看,对支持的培训需求和提高应用程序支持所需资源的可用性,会在项目的后期出现。随着移植项目技术方面的工作趋于完成,商业内容也就逐渐显现。
  • [技术干货] .NET生态系统概览
    2002 年,.NET 发布。在接下来的 12年多时间里,.NET 开发社区以看似稳定的速度增长。2010年以后,情况开始迅速变化。微软预见到了生态系统的变化,采纳了开源开发理念,甚至收购了 GitHub。出现这样的变化,说明 .NET Framework 开发人员已经准备好迎接刚刚开始的加速发展。微软后来收购了全球领先的软件开发平台 GitHub,而 .NET Framework 开发人员也做好了迎接加速发展的准备。2014 年 11 月,.NET Core 诞生。对于.NET 生态系统来说,这预示着一个革命性的开源新时代的到来,但这并非一帆风顺。困惑和沮丧随之而来;开发人员还没有准备好迎接如此巨大的变化。.NET Standard 开发人员必须了解 .NET Standard,但是多年以后,.NET Standard 仍然让那些不知道如何使用它的人感到困惑——他们将它误认为运行时,而它实际上只是一个规范。作为一个目标框架别名(TFM),开发人员可以编写面向 .NET Standard 的类库,并使生成的包可以供 .NET Core 或 .NET Framework 应用程序使用。考虑下多平台。借助编译器指令,包的作者可以编写条件代码,以 .NET Core 或 .NET Framework 为编译目标。这种标准化可以提供多种满足标准的实现。使用 .NET Standard,版本可以与 .NET Core 和 .NET Framework 实现保持一致。.NET Standard 是一个规范。它代表所有.NET 平台都必须实现的一组 API。——Immo Landwerth.NET是跨平台的开发栈。它有一个标准库,称为.NET Standard Library,其中包含了大量的APIs。这个标准库由各种.NET运行环境实现:.NET Framework、.NET Core和Xamarin-flavored Mono。.NET Framework就是现有的开发人员一直使用的.NET Framework。它实现了.NET Standard Library,就是说任何仅依赖于.NET Standard Library的代码都可以在.NET Framework上运行。它包含了其他Windows专用的APIs,比如说用于Windows桌面开发的APIs如Windows Forms和WPF。.NET Framework针对构建Windows桌面应用程序进行了优化。.NET Core是针对服务器工作负载优化的新的跨平台运行环境。它实现了.NET Standard Library,就是说任何使用.NET Standard Library的代码都可以在.NET Core上运行。该运行环境适合新的Web开发栈ASP.NET Core使用。它是现代的、高效的并为处理大规模的服务器和云工作负载设计的。Xamarin-flavored Mono是Xamarin应用程序的运行环境。它实现了.NET Standard Library,就是说任何仅依赖于.NET Standard Library的代码都可以在Xamarin应用程序上运行。它包含了其他iOS、Android、Xamarin.Forms和Xamarin.Mac使用的APIs。它针对在iOS和Android上构建移动应用程序进行了优化。多亏有.NET Standard,特别是在.NET Standard 2.0中交付的APIs,开发人员不需要太多地考虑哪个运行环境来运行他们的应用程序。跟上.NET的人可能有兴趣了解我们为某些特定用例优化的运行环境(例如说,为移动应用和游戏优化的Mono),但是在极大多数程度上,开发人员只需要知道,无论他们有什么需求,我们都已经为他们满足了。当谈论到选择运行环境的问题,选择方式应该是这样的:.NET Framework是以Windows为中心的框架,为Windows开发人员提供最好的服务。如果你正在搭建Windows为中心的应用程序,请你选择它。.NET Core是云优化引擎,它是跨平台的。它使用相同的高性能JIT编译器,但在所有支持的操作系统(Windows、Linux、macOS)上运行代码。它没有特定的WindowsAPIs,因为这有悖于跨平台的目标。Mono是用于移动应用和Apple平台(Android、iOS、watchOS、tvOS)的运行环境,用于游戏控制器和Unix桌面应用程序。统一 .NET Core 和 .NET Framework在 2019 年微软 Build 大会上,他们宣布了 .NET 5,统一了 .NET Core 和 .NET Framework.以后将只有一个 .NET,你可以使用它开发面向 Windows、Linux、macOS、iOS、Android、 tvOS、watchOS、WebAssembly 等平台的应用。——Richard Lander是的,没错,但值得再重复一遍,.NET 5 的目标是统一 .NET Framework 和 .NET Core。要使这一公告成为现实还有许多工作要做。将在2020年11月发布正式版,目前已经发布了RC1。这将给开发人员社区带来极大的帮助,因为它让事情变得简单!微软还利用了 Mono 运行时和 .NET Core 的成果。乍一看可能有点吓人(再强调一遍,作为开发人员,我们需要拥抱变化而不是害怕它),但是请放心,为实现 .NET 5 所做的所有工作都是以 .NET Core 和 Mono 的成功经验为基础。.NET 的统一在真正意义上终结了过去多年来困扰开发人员社区的.NET 生态系统分裂的问题。目前还不清楚 .NET Standard 是否会继续存在。 未来展望虽然我们很容易沉溺于过去,对过去的担忧和挫折牢骚满腹,但我们必须前进。也许,最合理的方法之一就是统一 .NET Core 和 .NET Framework……我敢说:“让 .NET 再次变得伟大!”也许我的说法太过了,但我们还是讨论一下未来吧。微软将把我们引向何方?让我们先退一步,讨论一下我们从哪里来,然后再深入讨论我们要到哪里去。并不是所有的.NET 开发人员都知道他们的代码是如何编译的以及最终生成了什么。从一开始.NET 就是基于即时(JIT)编译器将中间语言(IL)翻译成最优的机器码。——Richard Lander回顾我之前提到的 Mono 项目,我们知道,在.NET 预编译(AOT)方面已经做了大量的工作。Mono 已经实现了业界领先的 LLVM 编译器基础设施。Mono AOT 编译器可以将.NET 代码编译成一个可以在机器上运行的本地可执行代码,就像 C++ 代码一样。——Richard Lander重要的是要认识到,在 .NET Core 3.0 之后,不会再移植任何 .NET Framework 特性。再说一次,.NET 5 预计在 2020 年 11 月推出,它会很快就会到来。你可以问下自己,“在此期间我们应该做些什么?”我们下次再讨论这个问题。以性能为中心的创新 微软官方建议您使用 .NET Core 开发新应用程序。如果可能的话,考虑将现有的 .NET Framework 应用程序移植到 .NET Core 也是一个好主意。新应用程序应该基于 .NET Core 构建。未来针对 .NET 的投入都将投入到 .NET Core 上。——Scott Hunter在.NET 生态系统中,.NET Core 一直处于创新的中心。它是一种可以替代 .NET Framework 的运行时,从头开始进行了完全重写;这使得针对性能的积极创新成为可能。 .NET Core 和 ASP . NET Core 的每次迭代都会在保证一致性的情况下进行改进。“减少分配”是一个非常常见的主题,为的是提升性能。一个新的行业术语诞生了:Allocaty(形容词:al·lo·caty)——进行不必要分配的代码。——David FowlerCoreCLR 和 CoreFX 的 GitHub 存储库不断收到大量的拉取请求,都是聚焦于通过减少分配来提高性能。这些努力直接导致了 ASP . NET Core 的诞生。根据 Tech Empower 的基准测试,.NET Core 已经成为世界上速度最快的 Web 服务器之一。见证这些进步令人难以置信,但它们源于大量时间和精力的付出以及社区的参与。微软是在开放的环境下发展的,这使得开源开发者社区能够为这些创新做出贡献。性能改进不局限于减少分配;通过利用硬件的固有特性,甚至可以获得更底层的收益。不断发展的 C#不用说,我是 C#语言的超级粉丝,而 .Net Core 是用 C#构建的并且以性能为中心。所以,我想在这里稍微讨论一下,这可能有点出乎意料。作为 .Net Core 的一个主题,只要有可能,以性能为重心的新功能不仅应该公开给公众使用,而且应该在内部使用。——Stephen ToubC# 7 及其后续的单点版本,以及现在的 C# 9,都触及到了社区采用的容忍界限。我非常信赖语言的进化。我支持这样做,但与此同时,我同情那些因为业务限制而无法采用新版本的开发人员。我能理解这样的担忧;您要问下自己——“价值定位是什么?”某些新特性以性能为中心,您可以根据自己的需要考虑这些特性。在 Twitter 上的一个帖子中,Nick Craver 说:“ C# 8 对我来说已经死了,”这句话大致的意思是“ StackExchange 要很多年才能升级到 C# 8。”这部分是因为某些 C#特性依赖于公共语言运行时 CLR 的更新。一个例子是“默认接口成员”特性,它目前依赖于 .NET Core 3.0。绝大多数其他特性只依赖于 C#编译器,这就完美了。C# 添加了很多灵感来源于函数式编程的功能,这让写代码变得更加愉悦。F#仍然是奇妙的函数式语言,它为C#很多功能激发了灵感,但似乎很难跻身主流语言行列。.NET正在努力成长为跨平台开发的强劲选择,但在保持相对性和增长方面仍然面临着挑战。虽然C#开发人员非常紧缺,但在学校、bootcamps和code academies中教C#的比例与Node和JavaScript相比少了太多。虽然.NET生态系统很强大且在不断增长,但它还是非常依赖于Microsoft。很少有大的公司为其OSS项目做出贡献。.NET 基金会 .NET 基金会是一个独立的组织,旨在促进围绕.NET 生态系统的开放开发和协作。它为社区和商业开发人员提供了一个论坛,旨在通过促进开放性和社区参与来鼓励创新,从而拓宽和强化 .NET 生态系统的未来。.NET 走向开源,采用MIT许可协议开源。 微软为了推动.NET开源社区的发展,2014年联合社区成立了.NET基金会。 2019年3月份 .NET 基金会完成第一次全面改选,2014年 .NET基金会的创始成员中有六位创始人,均非微软公司员工,随着微软的收购Xamarin,Miguel 也成了微软员工,Miguel 一直在努力让.NET基金会独立于微软。.NET基金会是一个独立的组织,支持.NET社区和开源,旨在拓宽和加强.NET生态系统和社区。这可以通过多种方式完成,包括项目指导,指导,法律和营销帮助,技术和财务支持设置等. 2014年以来已经有众多知名公司加入.NET基金会, 仅在平台项目中,.NET平台上有87%贡献者其实不在Microsoft工作。在.net conf 2019 AWS加入了支持.NET Foundation的.NET开源生态系统中越来越多的行业领导者,这些成员包括Microsoft,Google,Red Hat,JetBrains,Unity,三星,Pivotal,Insight和Telerik,AWS等公司。一定要访问他们的网站并参与其中,或者成为其中的一员。作为成员,你就有资格在董事会投票——同样,你也有资格成为董事会年度选举的候选人。  .NET 生态应用创新ARM 版本的 .NET Core,这是三星,微软和社区合作开发的产物,他们可以在树莓派,物联网等上使用.NET Core技术,三星在其基于 Linux 的 Tizen 操作系统中使用ARM版本的.NET Core,该操作系统正在驱动可穿戴设备和其他设备。 华为的鲲鹏服务器上也可以使用ARM版本的.NET Core技术移植.NET应用程序 。龙芯团队从2019年7 月份开始着手.NET Core的MIPS64支持研发,经过将近一年的研发,在2020年6月18日完成了里程碑性的工作,在github CoreCLR 仓库:https://github.com/gsvm/coreclr, 随后受到.NET社区的很大参与热情鼓舞之下,2020年7月7日,龙芯团队在github发布了 corefx:https://github.com/gsvm/corefx、core-setup :https://github.com/gsvm/core-setup。 2020年7月9日,龙芯团队发布了 dotnet 运行时、aspnet core 运行时与 sdk 的 EA 版本,见 loongson-dotnet/releases。同时在龙芯开源社区上线了.NET主页:http://www.loongnix.org/index.php/Dotnet。 富有意义的发展之路.NET 生态系统是一个不断变化的生态圈,我相信它正在朝着一个伟大的方向发展。有了开源和跨平台这两个关键优先事项,您就可以放心了。当我意识到 .NET Core 和 .NET Framework 是 .NET 生态系统的压力源,并导致了 .NET 5 的统一时,我个人感到振奋。虽然这几年颇痛苦,但它也使这样的创新成为可能。我建议您尝试移植到 .NET Core,并开始使用 .NET Core 进行任何新的开发;这就是未来。尽管 .NET Standard 的方向尚且未知,但在有进一步的消息之前,我们仍然建议使用它最大化代码重用。我希望,无论决定是什么,影响都不会太大。
  • [问题求助] C# sdk在.net core环境下无法正确运行
    将原.net framework4.6.1文件及代码导入到.net core 3应用以后,无法获取token,具体在HWOcrClientToken.cs中GetHttpToken()函数无响应。请添加.net core sdk示例,否则应用无法在linux环境下部署,谢谢。另示例sdk在.net framework4.8下也无法正确运行。
  • [问题求助] 软开云对于.net开发(windows)的友好性怎么样?
    问题背景最近有.net开发的需求问题描述考虑在软开云上进行.net开发,不太清楚软开云对于.net开发(windows)支不支持,友好性怎么样,会不会有影响?可能存在哪些问题?
  • [问题求助] .netframework 通过 mono编译是否能允许在鲲鹏上?
    问题一、网上有部分资料说.netframework 通过 mono编译 可以解决windows强依赖的问题,能在linux上运行,请问专家们是否可以针对此情况给出相对客观真实的分析,如何判断是否可以?是否涉及大量修改工作量?问题二、华为官网也有文档说明,基于mono完成dotnet项目构建。是否意味着.netframwork c# 开发的 通过mono完成dotnet项目构建 也可以在arm上跑?如何判断是否可以?是否涉及大量修改工作量?以下是相关链接:https://support.huaweicloud.com/bestpractice-codeci/codeci_practice_1020.html问题三:、伙伴扫描提示缺少 jave-1.0.3.jar 依赖库文件,找了很久没有找到,麻烦专家帮下忙,感谢。
  • .net core迁移实践-乐石NisMES鲲鹏适配
    1 介绍1.1 .NET Core 介绍.NET Core是.NET的跨平台版本,用于构建网站,服务和控制台应用程序。具有以下特性:跨平台: 可在 Windows、macOS 和 Linux 操作系统上运行。跨体系结构保持一致: 在多个体系结构(包括 x64、x86 和 ARM)上以相同的行为运行代码。兼容性: .NET Core 通过 .NET Standard 与 .NET Framework兼容。ASP.NET Core 是一个跨平台的高性能开源框架,用于生成基于云且连接 Internet 的新式应用程序。.NET Core SDK包含.NET Core Runtime、ASP.NET Core Runtime和Desktop Runtime,其中.NET Core Runtime、ASP.NET Core Runtime均支持Linux ARM64,而Desktop Runtime仅支持Windows。Github地址:https://github.com/dotnet1.2 NisMES介绍    “乐石NisMES”系乐石团队在全面考察中国制造业发展状况的基础上,结合当前国内生产企业现状,自主研发设计的一套适应并满足智能制造信息化需求的整体解决方案。是基于准时制生产、柔性制造、全面质量管理、零库存、零故障等精益生产理念的MES系统。目前已在机械、电子、五金等离散制造行业及陶瓷行业的智能制造系统建设方面积累了丰富经验。帮助中国制造企业合理有效的解决制造业设备故障率高、生产周期长、产品质量低、库存过大这四个主要问题,通过各个模块下科学的管理模式和先进的信息化技术,提高企业的生产效率和市场竞争力,实现智能制造管理。 2 迁移概述2.1 迁移分析现状:操作系统:windows server 2012部署方式:IIS应用框架:.NET Core 2.1ORM框架:EF Core 2.1数据库:Sql Server 2008 R2缓存中间件:redis分析:操作系统:考虑到使用许可问题以及鲲鹏cpu架构为ARM64V8,将操作系统由windows换成Ubuntu Server 18.04。部署方式:.NET Core 在Ubuntu中环境部署步骤较多,若直接安装,不方便之后的应用迁移,所以使用Docker作为部署方式。应用框架:查看dockerhub中ASP.NET Core Runtime 官方镜像,未找到 2.1版本的 linux arm64 镜像,而 3.1版本支持,ASP.NET Core Runtime将升级到3.1版本.数据库:Sql Server数据库换成 PostgreSQL。ORM框架:考虑到 EF Core 2.1升级到3.1版本中断功能,以及EF Core本就支持Postgres等主流数据库,故暂时不升级。2.2 迁移建议ARM64支持.NET Core 3.1及以上版本,本文使用.NET Core 3.1版本;操作系统建议使用Ubuntu 18.04版本,后续所有的操作都是基于Ubuntu 18.04。表2-1 IIS迁移建议组件迁移建议windows server 2012Ubuntu Server 18.04 (ARM64V8).NET Core 2.1.NET Core 3.1EF Core 2.1EF Core 2.1暂不变更redisRedis-暂不变更SQL ServerPostgre SQL2.3 迁移参考链接从 ASP.NET Core 2.1 迁移到 2.2https://docs.microsoft.com/zh-cn/aspnet/core/migration/21-to-22?view=aspnetcore-3.1&tabs=visual-studio从 ASP.NET Core 2.2 迁移到3.0https://docs.microsoft.com/zh-cn/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio从 ASP.NET Core 3.0 迁移到3.1https://docs.microsoft.com/zh-cn/aspnet/core/migration/30-to-31?view=aspnetcore-3.1&tabs=visual-studio.NetCore2.1项目升级到.NetCore3.1的一点记录https://www.cnblogs.com/hunanzp/p/12508003.html数据库架构迁移:使用EFCore的迁移功能https://docs.microsoft.com/zh-cn/ef/core/managing-schemas/migrations/?tabs=vs#create-a-migration3 环境准备3.1 操作系统Ubuntu Server 18.04使用华为云鲲鹏镜像。3.2 安装docker请参照:https://www.huaweicloud.com/kunpeng/software/docker.html 4 NisMES 鲲鹏适配4.1 应用框架升级到 .NET Core 3.14.1.1 项目文件调整(.csproj)目标框架 改为 .NET Core 3.1移除包 Microsoft.AspNetCore.App 的引用,这个会默认包含在框架中添加包 Microsoft.AspNetCore.Mvc.NewtonsoftJson 的引用注: .NET Core 3.0 已经从共享框架中删除了Newtonsoft.Json,并引入System.Text.Json 类库并作为默认JSON序列化包,为兼容已有功能需要引入Microsoft.AspNetCore.Mvc.NewtonsoftJson包。4.1.2 Program.cs 文件调整将IWebHostBuilder 改为IHostBuilder将 Web 服务器的启动代码放到 ConfigureWebHostDefaults 中4.1.3 Startup.cs 文件调整ConfigureServices方法修改Configure方法修改将IHostingEnvironment 改为IWebHostEnvironment 参照:https://www.cnblogs.com/sanshi/p/11640318.html4.2 数据库迁移4.2.1 Docker中安装postgres参照镜像说明4.2.2 数据库架构迁移使用EFCore的迁移功能n  模型项目引入EFCore、Postgre相关的包n  DbContext数据库访问上下文类中指定的连接的数据库类型、连接字符串、包含一个无参构造函数,其他模式见 Design-time DbContext Creation;n  执行Add-Migration命令,根据已定义的模型类(CodeFirst模式)生成db创建脚本n  执行Update-Database命令,根据db创建脚本创建数据库4.2.3 迁移sqlserver中的数据到postgres使用工具navicat4.3 安装redis参照镜像说明4.4 发布程序n  VS发布程序到本地目录n  使用WinSCP上传程序文件到Ubuntu服务器 n  构建镜像n  运行容器 5 问题解决1、 数据库中字母大小写问题:Postgres区分大小写,SqlServer不区分大小写,代码中应注意区分大小写,否则可能有查不到数据的问题;2、 日期时间显示错误问题:Docker容器中时区与宿主机不一致,dockerfile中要指定时区Asia/Shanghai,否则显示的日期时间可能不正确;3、 文件路径问题:linux中路径分割符为 / ,windows中路径分割符为 \,涉及路径拼接时不要直接使用/或\符号,而是使用 Path.Combine方法,否则可能会有找不到文件的问题;4、 迁移数据架构时实体上注解问题:实体上的形如 [Column(TypeName = "decimal(18, 6)")] 这种注解应去除,否则生成数据库表结构时可能失败(不同数据库类型可能不同);
  • [产品体验官] 华为云鲲鹏弹性云服务器KC1体验及评测-.Net生产环境部署
    1、开发场景针对.Net开发的应用,目前已跨平台支持Linux,针对ARM芯片的服务器,验证生产环境是否满足.net。2、使用体验服务器规格鲲鹏通用计算增强型 | kc1.xlarge.2 | 4vCPUs | 8GB  弹性公网IP:139.9.129.109  采用SSH客户端连接服务器 查看计算机名查看系统内核架构:uname-a  aarch64查看操作系统版本 cat  /etc/os-release查看cpu信息:lscpu查看内存信息 cat /proc/meminfo查看磁盘信息 lsblk查看网卡信息,内网IP为192.168.0.75检查网络通讯是否正常开始安装jexus中间件,自带兼容.net的mono环境,下载速度1.09MB/S 安装成功启动jexus服务,提示失败查看jexus服务状态,提示无法执行二进制文件经排查在线安装不适合ARM环境,重新下载arm版本安装成功之后,查看Mono版本号,并启动服务,默认80端口已启动上传本地CMS应用,安全组打开80端口,外网验证是否正常访问输入外网地址http://139.9.129.109/JLadmin/login.aspx,成功访问.net应用后台需求建议:①比较容易上手,没有太多额外的学习成本 。②相比X86的云服务器,在安装应用方面,需要注意安装版本是否支持ARM。③操作界面友好,改版之后给人感觉更加清新,用户体验更好。④使用过程中基本上与X86 Linux体验一致,主要是应用软件生态需要更加完善。3.满意度及推荐度:公司在购买云服务器时,我会推荐使用华为云的鲲鹏服务器,理由:服务器稳定可靠,支持华为芯片,共建ARM生态。华为云ID zss33266
  • 请问构建环境支持.net core 3.0吗?
    目前选择.net framework 4.8,能支持到.net core 2.2的构建。有什么方式能支持.net core 3.0么?
  • [热门活动] 构建环境能支持.net core 3.0吗?
    构建环境能支持.net core 3.0吗?选择.net framework 4.8的时候,能支持到2.2。
  • [问题求助] 这个谁能负责,有没有.net的sdk
    或者视频监控提供了哪些语言的sdk?为啥在官网一点也没有写?
  • [问题求助] .Net Core下使用MQTT协议直连服务(已解决存档)
    开发工具Visual Studio 2019,.net core 2.2和.net framework 4.7.2都一样的情况MQTTnet版本v3.0.8项目产品的Profile和AgentLiteSdk Demo一样的,C语言的Demo成功连接添加设备时选择的直连设备配置信息设备名称 agentlite_demo_0015 设备ID 00b1db5e-5331-4ade-8b62-6c670e6c8d98 密钥 9e4fbd64f6be2337732a完整代码class Program { private static IMqttClient mqttClient; private static async Task ConnectMqttServerAsync() { if (mqttClient == null) { mqttClient = new MqttFactory().CreateMqttClient(); mqttClient.UseConnectedHandler(handle => { mqttClient.SubscribeAsync(new TopicFilter() { Topic = "/huawei/v1/devices/00b1db5e-5331-4ade-8b62-6c670e6c8d98/data/json", QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce }); Console.WriteLine(handle.AuthenticateResult.RetainAvailable); }); mqttClient.UseApplicationMessageReceivedHandler(handle => { Console.WriteLine(Encoding.Default.GetString(handle.ApplicationMessage.Payload)); }); } try { var utctime = DateTime.UtcNow.ToString("yyyyMMddhh"); var pwd = Encrypt("9e4fbd64f6be2337732a", utctime); var options = new MqttClientOptionsBuilder() .WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V311) .WithClientId($"00b1db5e-5331-4ade-8b62-6c670e6c8d98_0_1_{utctime}") .WithTcpServer("49.4.93.24", 8883) .WithCredentials("00b1db5e-5331-4ade-8b62-6c670e6c8d98", pwd ) .WithTls(new MqttClientOptionsBuilderTlsParameters() { AllowUntrustedCertificates = false, UseTls = true, Certificates = new List<byte[]> { new X509Certificate2("rootcert.pem").Export(X509ContentType.Cert) }, CertificateValidationCallback = delegate { return true; }, IgnoreCertificateChainErrors = false, IgnoreCertificateRevocationErrors = false }) .WithCleanSession() .Build(); var options1 = new MqttClientOptions() { ProtocolVersion = MQTTnet.Formatter.MqttProtocolVersion.V311, ClientId = $"00b1db5e-5331-4ade-8b62-6c670e6c8d98_2_1_{utctime}", Credentials = new MqttClientCredentials() { Username = "agentlite_demo_0015", Password = Encrypt2("9e4fbd64f6be2337732a", utctime) }, ChannelOptions = new MqttClientTcpOptions { Server = "49.4.93.24", Port = 8883, TlsOptions = new MqttClientTlsOptions() { Certificates = new List<byte[]> { new X509Certificate2("rootcert.pem").Export(X509ContentType.Cert) }, CertificateValidationCallback = delegate { return true; }, UseTls = true } }, }; var result = await mqttClient.ConnectAsync(options); //var result = await mqttClient.ConnectAsync(options1); Console.WriteLine(result.ResultCode); } catch (Exception ex) { Console.WriteLine(ex.Message); } } public static byte[] Encrypt2(string message, string secret) { secret = secret ?? ""; var encoding = new System.Text.UTF8Encoding(); byte[] keyByte = encoding.GetBytes(secret); byte[] messageBytes = encoding.GetBytes(message); using (var hmacsha256 = new HMACSHA256(keyByte)) { return hmacsha256.ComputeHash(messageBytes); } } public static string Encrypt(string message, string secret) { secret = secret ?? ""; //var encoding = new System.Text.ASCIIEncoding(); var encoding = new System.Text.UTF8Encoding(); byte[] keyByte = encoding.GetBytes(secret); byte[] messageBytes = encoding.GetBytes(message); using (var hmacsha256 = new HMACSHA256(keyByte)) { byte[] hashmessage = hmacsha256.ComputeHash(messageBytes); return Convert.ToBase64String(hashmessage); } } static async Task Main(string[] args) { try { _ = Task.Run(async () =>   {   await ConnectMqttServerAsync();   }); while (mqttClient?.IsConnected != true) { await Task.Delay(1000); } var result = await mqttClient.PublishAsync(topic: "/huawei/v1/devices/00b1db5e-5331-4ade-8b62-6c670e6c8d98/command/json", payload: ""); } catch (Exception ex) { Console.WriteLine(ex.Message + ex.StackTrace); } } }返回的错误是:Connecting with MQTT server failed (BadUserNameOrPassword).
  • [问题求助] 【趁热打“帖”】.Net下使用Agent Lite Sdk成果与问题
    .Net要想使用C/C++的方法,根据经验使用[DllImport]特性声明方法的定义和参数,就可以和使用本地静态方法一样。因为使用Agent Lite Sdk想集成到.Net平台上,和业务集成到一起。根据以上思想已经完成了一部分工作,IOTA_Init(configPath, logPath); IOTA_Bind(pcMac, ref stDeviceInfo);IOTA_Login();IOTA_ServiceDataReport(HW_GeneralCookie(), aszRequestId, pcSensorDeviceID, pcServiceId, pcServiceProperties);以上逻辑都实现了,也能发送数据给平台。现在的问题是回调函数和平台下发命令中的HW_MSG参数,用C#不知道如何解析,因为给到的定义是HW_MSG看样子只是一个指针,用的地方很多,但是没有具体定义结构C的代码里是typedef struct stru_HW_MSG     { HW_INT unused; } * HW_MSG;  /**< @brief Caas message type. */ //注册广播接收器对设备绑定结果进行相应处理 HW_BroadCastReg(IOTA_TOPIC_BIND_RSP, Device_RegResultHandler); /*连接回调执行*/ HW_INT Device_RegResultHandler(HW_UINT uiCookie, HW_MSG pstMsg) {     pcDeviceId = HW_MsgGetStr(pstMsg, EN_IOTA_BIND_IE_DEVICEID);     uiRegRet = HW_MsgGetUint(pstMsg, EN_IOTA_BIND_IE_RESULT, EN_IOTA_BIND_RESULT_FAILED); }C#的代码是 [StructLayout(LayoutKind.Sequential)]  public struct HW_MSG  {      public int unused;  }  //定义一个回调委托  public delegate int BroadHandler(int uiCookie, ref HW_MSG pstMsg);    [DllImport(@"hwsys", EntryPoint = "HW_BroadCastReg", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]  public static extern int HW_BroadCastReg(string pcTopic, BroadHandler pfnReceiver);   //实际执行回调的方法,方法能够被执行 public static int Device_RegResultHandler(int uiCookie, ref HW_MSG pstMsg) {     var pcDeviceId = HW_MsgGetStr(pstMsg, (int)EN_IOTA_BIND_IE_TYPE.EN_IOTA_BIND_IE_DEVICEID);          //在这里解析pstMsg遇到困难,不知道如何接触结构     // 我个人觉得pstMsg更像是一个IntPtr地址,但是没搞成功 }HW_MSG这个对象是个指针,C#中如何解析真正的值呢?模仿c的做法HW_MsgGetStr也得不到内容十万火急,高手帮忙,如果SDK的作者能看到更好了C#里面有一个对象 Marshal 专门用来做托管和非托管对象的转换操作。试了很多办法,都没找到合适的。
总条数:56 到第
上滑加载中