原文:https://natemcmaster.com/blog/2017/12/21/netcore-primitives/
linux上安装dotnet参照:https://blog.csdn.net/u010476739/article/details/100144287
实验目的:
探究与.netcore编译和运行有关的*.deps.json, *. runtimeconfig.json,,*.dll文件
实验环境:
- centos7.6 x 64
- dotnet-sdk-2.2.401-linux-x64.tar.gz
- dotnetsdk是按照博文.netcore入门1:linux上安装.net core sdk 2.2(离线安装和yum仓库安装)上面介绍的使用离线安装包安装的,安装到了/usr/local/dotnet目录
一、使用Roslyn编译器第一个CS文件
1.1 在目录/root下新建文件“Program.cs”
Program.cs:
class Programe{
public static void Main(string[] args){
System.Console.WriteLine("Hello world");
}
}
1.2 使用csc.dll编译这个文件生成Program.dll
[root@localhost ~]# ll
总用量 8
-rw-------. 1 root root 1215 8月 29 11:28 anaconda-ks.cfg
-rw-r--r--. 1 root root 116 9月 2 15:47 Program.cs
[root@localhost ~]# dotnet /usr/local/dotnet/sdk/2.2.401/Roslyn/bincore/csc.dll -reference:/usr/local/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/ref/netcoreapp2.2/System.Runtime.dll -reference:/usr/local/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/ref/netcoreapp2.2/System.Console.dll -out:Program.dll Program.cs
Microsoft (R) Visual C# Compiler version 3.2.0-beta2-19303-01 (c9689b7a)
Copyright (C) Microsoft Corporation. All rights reserved.
[root@localhost ~]# ll
总用量 12
-rw-------. 1 root root 1215 8月 29 11:28 anaconda-ks.cfg
-rw-r--r--. 1 root root 116 9月 2 15:47 Program.cs
-rw-r--r--. 1 root root 3584 9月 2 16:14 Program.dll
1.3 运行Program.dll
命令行直接运行:dotnet Program.dll
[root@localhost ~]# dotnet Program.dll
A fatal error was encountered. The library 'libhostpolicy.so' required to execute the application was not found in '/root/'.
Failed to run as a self-contained app. If this should be a framework-dependent app, add the /root/Program.runtimeconfig.json file specifying the appropriate framework.
这里提示的很明显,这个dll需要使用“Program.runtimeconfig.json”文件来指定运行的框架。
新建文件/root/Program.runtimeconfig.json,内容如下:
{
"runtimeOptions": {
"framework": {
"name": "Microsoft.NETCore.App",
"version": "2.2.0"
}
}
}
再次运行:dotnet Program.dll
[root@localhost ~]# dotnet Program.dll
Hello world
这个时候正常运行了,它所依赖的System.Runtime.dll、System.Console.dll都在Program.runtimeconfig.json文件中以运行目标框架的方式指定了。
二、引用外部依赖再编译运行
2.1 准备Newtonsoft.Json包
下载地址:https://www.nuget.org/packages/Newtonsoft.Json/12.0.2
新建文件夹/root/packages/Newtonsoft.Json/12.0.2:
[root@localhost ~]# mkdir -p ./packages/Newtonsoft.Json/12.0.2
将下载好的newtonsoft.json.12.0.2.nupkg文件解压到/root/packages/Newtonsoft.Json/12.0.2中,解压后的目录为:
2.2 修改Program.cs文件内容如下:
class Programe{
public static void Main(string[] args){
System.Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(new { greeting = "Hello World!" }));
}
}
2.3 编译Program.cs
[root@localhost ~]# dotnet /usr/local/dotnet/sdk/2.2.401/Roslyn/bincore/csc.dll -reference:/usr/local/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/ref/netcoreapp2.2/System.Runtime.dll -reference:/usr/local/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/ref/netcoreapp2.2/System.Console.dll -reference:./packages/Newtonsoft.Json/12.0.2/lib/netstandard1.3/Newtonsoft.Json.dll -reference:/usr/local/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/ref/netcoreapp2.2/System.Collections.dll -out:Program.dll Program.cs
Microsoft (R) Visual C# Compiler version 3.2.0-beta2-19303-01 (c9689b7a)
Copyright (C) Microsoft Corporation. All rights reserved.
warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'Newtonsoft.Json' matches identity 'System.Runtime, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy
Program.cs(3,34): warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'Newtonsoft.Json' matches identity 'System.Runtime, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy
[root@localhost ~]#
可以看到编译成功,后面出现的警告是因为Newtonsoft.Json.dll的版本问题,先不用理会这个(版本兼容)。
2.4 运行Program.dll
[root@localhost ~]# dotnet Program.dll
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'. The system cannot find the file specified.
已放弃
可以看到,直接运行是报错的,提示找不到Newtonsoft.Json,我们可以将Newton.Json.dll文件从引用的目录直接拷贝到Program.dll同目录来,然后运行:
[root@localhost ~]# dotnet Program.dll
{"greeting":"Hello World!"}
直接将外部依赖拷贝到生成的dll文件的同目录,这种方法也是ide工具用的方法也是我们最容易理解的。
现在来看另外一种方法:
首先删除掉同目录的Newtonsoft.Json.dll文件
然后添加文件Program.deps.json,在这个文件中写入依赖信息如下:
{
"runtimeTarget":{
"name":".NETCoreApp,Version=v2.2.0"
},
"targets":{
".NETCoreApp,Version=v2.2.0":{
"Newtonsoft.Json/12.0.2":{
"runtime":{
"lib/netstandard1.3/Newtonsoft.Json.dll":{}
}
}
}
},
"libraries":{
"Newtonsoft.Json/12.0.2":{
"type":"package",
"serviceable":false,
"sha512":""
}
}
}
接着修改文件Program.runtimeconfig.json,在这个文件中写入依赖程序集的搜索路径
{
"runtimeOptions":{
"framework":{
"name":"Microsoft.NETCore.App",
"version":"2.2.0"
},
"additionalProbingPaths":[
"./packages/"
]
}
}
最后运行如下:
[root@localhost ~]# ll
总用量 24
-rw-------. 1 root root 1215 8月 29 11:28 anaconda-ks.cfg
drwxr-xr-x. 3 root root 29 9月 2 16:33 packages
-rw-r--r--. 1 root root 181 9月 2 16:37 Program.cs
-rw-r--r--. 1 root root 460 9月 2 16:56 Program.deps.json
-rw-r--r--. 1 root root 4608 9月 2 16:40 Program.dll
-rw-r--r--. 1 root root 156 9月 2 16:56 Program.runtimeconfig.json
[root@localhost ~]# dotnet Program.dll
{"greeting":"Hello World!"}
可以看到运行成功了!