.netcore入门3:vs2019开发.netcore 控制台程序(编译、打包、发布)(.netcore 2.2)

实验环境:

  • win10 x64
  • vs2019 16.3
  • .netcore 2.2

实验目的:

  • 探究.net core程序的开发的编译、打包、发布过程
  • 探究vs工程结构

一、新建.net core控制台程序

新建项目:
在这里插入图片描述
新建成功后vs组织结构:
在这里插入图片描述
此时磁盘的组织结构为:
在这里插入图片描述
查看主要的三个文件内容:consoledemo.slnconsoledemo.csprojProgram.cs
consoledemo.sln:


Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29215.179
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "consoledemo", "consoledemo.csproj", "{5AD28B6C-4558-4282-A4E7-203B0A23F17F}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Release|Any CPU = Release|Any CPU
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{5AD28B6C-4558-4282-A4E7-203B0A23F17F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{5AD28B6C-4558-4282-A4E7-203B0A23F17F}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{5AD28B6C-4558-4282-A4E7-203B0A23F17F}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{5AD28B6C-4558-4282-A4E7-203B0A23F17F}.Release|Any CPU.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
	GlobalSection(ExtensibilityGlobals) = postSolution
		SolutionGuid = {84FCC3C5-89AF-42C4-90E2-99AA33719410}
	EndGlobalSection
EndGlobal

consoledemo.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
  </PropertyGroup>

</Project>

Program.cs:

using System;

namespace consoledemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}
  1. 从上面的图中可以看出,这个控制台运行在netcoreapp2.2下面,那么它指定的运行时环境在哪个位置呢:
    在这里插入图片描述
    为什么选择这个版本,而不是其他的,是因为工程文件中指定的版本是2.2,那么就从2.2向上找最接近的
  2. 从vs中只观察到依赖sdk,那么依赖的sdk中具体的库文件在哪呢:
    在这里插入图片描述
    在这里插入图片描述

二、编译工程

2.1 工程右键->重新生成

在这里插入图片描述
生成后的目录:
在这里插入图片描述
解释一下上面文件的意义:

  • consoledemo.dll

    这个就是我们写的代码编译后的结果,最主要的!

  • consoledemo.runtimeconfig.json

    如果我们编译生成的dll文件是依赖运行主机上的dotnetcore环境的话,那么我们需要这个文件来执行运行的dotnet版本和其他一些信息(如:依赖的外部dll的搜索路径)。一般我们需要这个文件来执行运行的dotnetcore版本!

  • consoledemo.deps.json

    这个文件主要是用来描述外部依赖的,当我们引用了其他包的时候,比如“Newtonsoft.Json”那么我们需要在这个文件中标明一下(注意:这里只是标明程序集名称并没有标明搜索路径),当然如果我们把“Newtonsoft.Json”直接放在了这个目录里就不需要这个文件了;一般我们在调试的时候,ide不会把“Newtonsoft.Json”拷贝到这个目录的,所以调试的时候需要,而我们发布的时候ide是把“Newtonsoft.Json”拷贝到这个目录的,所以发布的时候一般不需要。

  • consoledemo.runtimeconfig.dev.json

    这个文件和“consoledemo.deps.json”配合使用在ide的调试环境。上面在介绍“consoledemo.deps.json”文件的时候有解释到它没有标明程序集的搜索路径,那么在ide调试的时候是怎么找到“Newtonsoft.Json”的呢?这就是“consoledemo.runtimeconfig.dev.json”的作用了,在这个文件里可以配置程序集的搜索路径,不过只能配置绝对地址不能配置相对地址,也就是说它仅适合调试环境。

  • consoledemo.pdb

    这个文件是调试用的,不做解释。

2.2 运行dll文件

直接在命令行中运行:dotnet .\consoledemo.dll
在这里插入图片描述
那么,将上面的文件数量精简到最小化再运行:
在这里插入图片描述
此时打开consoledemo.runtimeconfig.json,观察里面内容:

{
  "runtimeOptions": {
    "tfm": "netcoreapp2.2",
    "framework": {
      "name": "Microsoft.NETCore.App",
      "version": "2.2.0"
    }
  }
}

可以看出“consoledemo.runtimeconfig.json”中就只是描述了dotnetcore运行时的版本。
将"consoledemo.dll"和"consoledemo.runtimeconfig.json"这两个文件上传到centos上运行:
在这里插入图片描述
效果也是一样的。

2.3 修改工程引入外部依赖:Newtonsoft.Json

nuget中引入依赖:
在这里插入图片描述
此时查看工程文件:consoledemo.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
  </ItemGroup>

</Project>

可以看到,在工程文件中引入了nuget依赖
接着修改Program.cs代码:

using System;

namespace consoledemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(new { name = "小明", age = 20 }));
        }
    }
}

2.4 重新编译工程

工程右键->重新生成,生成后的目录如下所示:
在这里插入图片描述
可以看到,还是这5个文件,此时你是不是奇怪Newtonsoft.Json怎么没有输出到这个目录?
答案是:这是“调试”模式不是“发布”模式。
此时打开consoledemo.deps.json,查看如下:

{
  "runtimeTarget": {
    "name": ".NETCoreApp,Version=v2.2",
    "signature": "4bf20b3f4b187ddd01af96ea47dda577c5263775"
  },
  "compilationOptions": {},
  "targets": {
    ".NETCoreApp,Version=v2.2": {
      "consoledemo/1.0.0": {
        "dependencies": {
          "Newtonsoft.Json": "12.0.2"
        },
        "runtime": {
          "consoledemo.dll": {}
        }
      },
      "Newtonsoft.Json/12.0.2": {
        "runtime": {
          "lib/netstandard2.0/Newtonsoft.Json.dll": {
            "assemblyVersion": "12.0.0.0",
            "fileVersion": "12.0.2.23222"
          }
        }
      }
    }
  },
  "libraries": {
    "consoledemo/1.0.0": {
      "type": "project",
      "serviceable": false,
      "sha512": ""
    },
    "Newtonsoft.Json/12.0.2": {
      "type": "package",
      "serviceable": true,
      "sha512": "sha512-rTK0s2EKlfHsQsH6Yx2smvcTCeyoDNgCW7FEYyV01drPlh2T243PR2DiDXqtC5N4GDm4Ma/lkxfW5a/4793vbA==",
      "path": "newtonsoft.json/12.0.2",
      "hashPath": "newtonsoft.json.12.0.2.nupkg.sha512"
    }
  }
}

可以看到,里面描述了依赖的Newtonsoft.Json信息,但是没有说明在哪个位置可以找到它。
再打开consoledemo.runtimeconfig.dev.json,查看内容如下:

{
  "runtimeOptions": {
    "additionalProbingPaths": [
      "C:\\Users\\AUAS\\.dotnet\\store\\|arch|\\|tfm|",
      "C:\\Users\\AUAS\\.nuget\\packages",
      "C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder"
    ]
  }
}

可以看到,这个文件里面清晰的描述了程序集的搜索路径,有了这个文件也就能根据“consoledemo.deps.json”声明的依赖信息去寻找具体的dll文件了。

2.5 运行生成的dll

首先删掉“consoledemo.pdb”文件,这个文件不用管。
打开命令行直接运行如下:
在这里插入图片描述
可以看到,能正常得到结果。
此时删除掉consoledemo.runtimeconfig.dev.json会怎么样呢?
在这里插入图片描述
可以看到,报错了,虽然在consoledemo.deps.json中声明了“Newtonsoft.Json”信息,但是由于缺少程序集的搜索路径仍然找不到“Newtonsoft.Json.dll”
如果把consoledemo.deps.json也删除掉怎么样呢?
在这里插入图片描述
可以看到,更是不行了!

三、打包工程

工程右键->打包,观察结果
在这里插入图片描述
可以看到在Debug目录下生成了一个consoledemo.1.0.0.nupkg文件,现在我们就可以方便的将这个nuget包发布出去共享了。
“consoledemo.1.0.0.nupkg”这个文件其实也是一个压缩包,查看解压后的目录:
在这里插入图片描述
这里解释一下里面的内容:

  • “[Content_Types].xml”文件、“_rels”目录、“package”目录都是和包的格式定义有关的,我们不用关心这些。
  • consoledemo.nuspec:这个文件描述了当前nuget包的元数据信息,包括:id、版本号、作者、依赖包,详细如下:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
  <metadata>
    <id>consoledemo</id>
    <version>1.0.0</version>
    <authors>consoledemo</authors>
    <owners>consoledemo</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Package Description</description>
    <dependencies>
      <group targetFramework=".NETCoreApp2.2">
        <dependency id="Newtonsoft.Json" version="12.0.2" exclude="Build,Analyzers" />
      </group>
    </dependencies>
  </metadata>
</package>
  • lib:里面是这个nuget包提供的程序集文件,按照运行环境组织目录,如下:
    在这里插入图片描述

四、发布工程

工程右键->发布:
在这里插入图片描述
点击“创建发布文件”后:
在这里插入图片描述
点击摘要下面的配置:
在这里插入图片描述
解释一下:

  • 目标框架:选择程序的运行时即可
  • 部署模式:“框架依赖”和“独立”二选一,它们又称为“framework-dependent”和“self-contained”
    框架依赖就是自己不携带和操作系统相关的东西,依赖于.netcore环境(也可以是具体操作系统上的.netcore,也可以是任意操作系统上的.netcore,后者称之为“可移植”)
    独立就是发布的时候将.netcore运行环境也打包了进来,好处是可以单独运行,坏处是生成的文件特别大,比如一个简单的”Hello World” 独立部署就要100多M,而框架依赖方式只有几十kb
  • 目标运行时:可以选择一个具体的操作系统版本,也可以选择“可移植”也就是任意操作系统版本,不过在部署模式选择“独立”的时候,这里就不能选择可移植了。

这里我们选择“框架依赖”、“可移植”(默认就是这两个),最后点击发布:
在这里插入图片描述
可以看到,发布后是把外部的依赖“Newtonsoft.Json.dll”输出了的,直接运行如下:
在这里插入图片描述
可以看到,运行正常!
那么发布后的这几个文件能精简到什么程度呢?
在这里插入图片描述
可以看到,只能精简到这了,再删除就会报错了,你可以试试。
此时将精简后的这三个文件放到linux上运行也是可以的,这里不再实验。
这里可能会有疑问,为什么“consoledemo.deps.json”可以删除?
因为它是记录的依赖信息,当具体的程序集都在当前目录的时候,它就不是那么重要了,还有你是否还记得nuget包里lib下存储的东西呢?
在这里插入图片描述

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jackletter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值