从.NETFramework1.0诞生之日起,一个可能被问过几百万遍的问题就出现了,“我写的.NET程序怎么才能够直接部署而不依赖.NETFramework呢?”那么,这种可能性有吗?
你可能听到的答案其实还蛮多,比如:
“做不到!”不论是初学者还是资深人士,给出这个答案都不意外,因为各自的思考方式不同。初学者是不太知道还有什么花头,而资深人士通常可能是懒得给你解释一大堆。
“打包.NETFramework安装包嘛!”能给你这个标准答案的人,相信已经是趟过这条河了,以后有技术问题,一定记得去找他/她问哈。
“用飞信虚拟机!”给出这种答案的人,其实很可能就是你身边隐藏的大神。就这一个名词背后就有太多故事可以大书特书,然而并非本文重点。有兴趣的朋友,可以在文后留言。如果人数足够多,我也不介意再写写。
对于多数个人用户来说,把小则几十兆,大则几百兆的.NETFramework安装包做到自己的程序安装包里面,在之前几年都是一个恐怖的事情。且不说网络下载之类以前带宽有限,即使是硬盘空间、光盘空间,也都是要留给其他重要数据(如图片、视频)的嘛,哪里容得下一个无关紧要的运行时。
所以.NET程序似乎从一开始就是为企业设计的,只有他们能够毫不厌烦地给机器装上这类东西,保证你的程序能够顺利运行。而独立开发人员,或者面向个人用户的软件开发公司,可能从技术选型那个时候就把.NET给放到一边去了。
不得不说Java在这方面就偷巧多了,在程序里面塞上一个其实并不小的JVM,就可以让你毫无察觉(比如Eclipse内置JVM)。
你也不要认为微软自己这么设计它日子就好过了。首先,.NETFramework就此成为了Windows系统上一个定时炸弹,安全补丁什么的,生命周期什么的,其实微软自己也觉得很不好搞。所以从WindowsServer内置.NETFramework1.1开始,微软自己也是噩梦连连。其次.NETFramework很快有了2.0/3.0/3.5/4.0/4.5/4.5.x/4.6.x/4.7.x这样林林总总的版本,安装和卸载可能导致的不稳定时有发生,于是4.x以上都变成了原地替换安装。是的,其实这也是微软给自己省事,虽然客户一点也不开心。如果算上Office插件系统和IIS上不同框架版本.NET程序的并行执行(sidebyside),我去,微软自己都快炸了。IIS还好一点,可以强制每个应用程序池只能用特定版本的.NETFramework,而Office要同时加载多个框架版本的插件,OMG,其实背后麻烦的要死要活。
到这里你就不会奇怪怎么一到了新平台.NETCore,微软就推荐大家用独立发布(self-contained)模式了吧。那么,这个模式到底怎么玩?
.NETCore独立发布其实这个部分真是简单到。。。不能再简单。安装完.NETCoreSDK,找个空目录,试下下面的命令,
dotnetnewconsole
dotnetpublish-cRelease--self-contained
OK,有没有卡住啊?
/usr/local/share/dotnet/sdk/2.0.2/Sdks/Microsoft.NET.Sdk/build/Microsoft.NET.RuntimeIdentifierInference.targets(,5):error:Itisnotsupportedtobuildorpublishaself-containedapplicationwithoutspecifyingaRuntimeIdentifier.PleaseeitherspecifyaRuntimeIdentifierorsetSelfContainedtofalse.[/Users/lextm/Projects/selfcontained/selfcontained.csproj]
一点也不要意外,微软这是提醒你还有些东西你需要提供,否则这个部署任务没法搞。
所以这种时候我们就只好打开工程文件看看,
ProjectSdk="Microsoft.NET.Sdk"
PropertyGroup
OutputTypeExe/OutputType
TargetFrameworknetcoreapp2.0/TargetFramework
/PropertyGroup
/Project
OK,试下把它改成这样,
ProjectSdk="Microsoft.NET.Sdk"
PropertyGroup
OutputTypeExe/OutputType
TargetFrameworknetcoreapp2.0/TargetFramework
RuntimeIdentifierswin-x86;win-x64;linux-x64;osx-x64/RuntimeIdentifiers
/PropertyGroup
/Project
加入的这一行指定了所有这个程序支持的操作系统平台,依次是:Windows32位,Windows64位,Linux64位,macOS64位。更多描述符资料,请查看官方文档。
下面回到命令行,继续发布,
dotnetpublish-cRelease--self-contained-rwin-x64
Microsoft(R)BuildEngineversion15.4.8.for.NETCore
Copyright(C)MicrosoftCorporation.Allrightsreserved.
selfcontained-/Users/lextm/Projects/selfcontained/bin/Release/netcoreapp2.0/win-x64/selfcontained.dll
selfcontained-/Users/lextm/Projects/selfcontained/bin/Release/netcoreapp2.0/win-x64/publish/
这样就做好了Windows64位需要的程序部署文件了。(别奇怪上面的路径分隔符,因为我是在Mac上面进行Windows程序的发布哦。)
打开这个publish文件夹,我们瞄下微软都干了什么。
神秘的发布目录
++,就TMD一个HelloKitty。。。World程序,硬是被塞了个文件!!!(你的菊花痛了吗?)不过骂归骂,把这个文件夹原样拷贝到Windows机器上,然后双击selfcontained.exe,它还就真的乖乖运行了。(怎么办,这么神奇,只能原谅它咯。)
注意力回到刚才的发布命令,那个-r开关就是用来指定目标平台的。如果要给多个平台发布,可以多次执行dotnetpublish,每次换下-r后面的描述符。
附赠秘籍:.NETILLinker不幸的是,并非所有的程序都如上面那个例子那么纤细苗条。
就问你大不大
呸!就问你大不大,一个HelloWorld六十多兆了。
虽然不太情愿,微软自己也只能承认这实在太不像话了,所以出了一个临时的解决方案,就是.NETILLinker。使用方法居然,一点也不复杂(真意外。。。)。
回到工程的根目录,运行
dotnetnewnuget
如此一来会创建一个nuget.config文件,
?xmlversion="1.0"encoding="utf-8"?
configuration
packageSources
!--ToinherittheglobalNuGetpackagesourcesremovetheclear/linebelow--
clear/
/packageSources
/configuration
将它修改一下,
?xmlversion="1.0"encoding="utf-8"?
configuration
packageSources
addkey="dotnet-core"value="哈尔滨白癜风白癜风怎么引起的原因