编程语言
首页 > 编程语言> > 开源电子书《WoW C#》

开源电子书《WoW C#》

作者:互联网

开源电子书《WoW C#》

.NET CLI简单教程和项目结构

 

本文内容来自我写的开源电子书《WoW C#》,现在正在编写中,可以去WOW-Csharp/学习路径总结.md at master · sogeisetsu/WOW-Csharp (github.com)来查看编写进度。预计2021年年底会完成编写,2022年2月之前会完成所有的校对和转制电子书工作,争取能够在2022年将此书上架亚马逊。编写此书的目的是因为目前.NET市场相对低迷,很多优秀的书都是基于.NET framework框架编写的,与现在的.NET 6相差太大,正规的.NET 5学习教程现在几乎只有MSDN,可是MSDN虽然准确优美但是太过琐碎,没有过阅读开发文档的同学容易一头雾水,于是,我就编写了基于.NET 5的《WoW C#》。本人水平有限,欢迎大家去本书的开源仓库sogeisetsu/WOW-Csharp关注、批评、建议和指导。

WHAT IS .NET CLI ?

.NET 命令行接口 (CLI) 工具是用于开发、生成、运行和发布 .NET 应用程序的跨平台工具链。


来源:.NET CLI | Microsoft Docs

.NET CLI是.NET官方的一个命令行工具。本文将介绍.NET CLI的几个主要的命令。并通过这几个命令来了解.NET控制台程序的项目结构。

不建议在学习阶段使用IDE

IDE是一种非常好的编程工具,但是,在初学阶段,并不建议使用IDE,因为IDE会让学习的人丧失对程序第一手的感知,有相当多的人在使用高级的框架开发的时候会出现没有IDE就不会开发的现象,我对IDE的看法是:“开发需要依赖IDE,但是不能依靠IDE”,也就是说,在没有IDE的情况下要依然能够会编写程序,会运行和发布程序。

没有IDE,那么就需要用.NET CLI创建、运行、构建和发布程序,用文本编写软件编写程序。文本编写软件可以用系统自带的记事本,但是更建议使用带“代码高亮和方法跳转”的文本编写软件,比如github开发的Atom或者微软的vscode

微软的Visual Studio 2019是一个比较好的.NET开发IDE。它的用法将在后面讲到。

事实上,强大的IDE(Visual Studio)在进行构建、编译和发布程序等操作的时候,依靠的也是.NET CLI

下载并安装.NET CLI

.NET CLI.NET SDK的一部分,下载.NET CLI的前提是去下载.NET SDK.NET SDK 是一组用于开发和运行 .NET 应用程序的库和工具。我们一般意义上讲的.NET就是指的.NET SDK

.NET 命令行接口 (CLI) 工具是用于开发、生成、运行和发布 .NET 应用程序的跨平台工具链。

.NET CLI 附带了 .NET SDK。 若要了解如何安装 .NET SDK,请参阅安装 .NET Core


来源:.NET CLI | Microsoft Docs

如果在CMD输入dotnet --version之后,有正确的关于dotnet版本的回应的话,那么就证明.NET SDK已经安装成功,作为.NET SDK一部分的.NET CLI也已经安装完毕。

(base) PS C:\Users\苏月晟\Desktop> dotnet --version
5.0.401

安装文本编辑器

前面已经讲了不建议在学习阶段使用高级的IDE,所以推荐一个好用的文本编辑器——Visual Studio Code。简称“vscode”。

vscode是微软的一款开源产品,它带有代码高亮功能,支持丰富的插件,可以直接调用终端,也可以直接在终端里面通过code命令直接调用vscode。更重要的是微软官方文档里面将.NET CLI的实例讲解和vscode的使用放在了一起。

下载安装完成之后,安装三个插件,安装方式是点击左侧的插件按钮,进行搜索安装。

三个插件如下:

这三个插件,一个是将vscode界面翻译成中文,一个是为编写和调试C#代码提供支持,最后一个插件是可以自动生成类注释和方法注释的模板。

.NET CLI 初级命令

初级命令就是newrunbuildpublish

dotnet new

根据指定的模板,创建新的项目、配置文件或解决方案。

dotnet new <TEMPLATE> [--dry-run] [--force] [-lang|--language {"C#"|"F#"|VB}]
    [-n|--name <OUTPUT_NAME>] [-o|--output <OUTPUT_DIRECTORY>] [Template options]

dotnet new -h|--help

常见的命令是dotnet new console -o <appname>

console是模板的名称,代表的是控制台程序。可以运行 dotnet new --list 以查看所有已安装模板的列表。

常用命令选项

项目结构

假设使用dotnet new console -o MyAppOne创建了一个名为MyAppOne的控制台应用,那么在没有经过编译运行的情况下MyAppOne文件夹下面的结构应该是这样的:

.
├── MyAppOne.csproj
├── Program.cs
└── obj

每个文件的作用

csproj 文件的本质是一个保存项目信息的xml文件。默认配置如下:

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

</Project>

项目系统和 MSBuild

.NET 应用是使用 MSBuild 从源代码中生成的。 项目文件(.csproj、.fsproj 或 .vbproj)指定目标和负责编译、打包和发布代码的关联任务 。 有引用目标和任务的标准集合的 SDK 标识符。 使用这些标识符有助于使项目文件较小且易于使用。

关于MSBuild的常用属性和命令行将在后面讲到。

dotnet run

无需任何显式编译或启动命令即可运行源代码。

dotnet run [-a|--arch <ARCHITECTURE>] [-c|--configuration <CONFIGURATION>]
    [-f|--framework <FRAMEWORK>] [--force] [--interactive]
    [--launch-profile <NAME>] [--no-build]
    [--no-dependencies] [--no-launch-profile] [--no-restore]
    [--os <OS>] [--project <PATH>] [-r|--runtime <RUNTIME_IDENTIFIER>]
    [-v|--verbosity <LEVEL>] [[--] [application arguments]]

dotnet run -h|--help

dotnet run的本质其实上是编译并运行。编译这一步它其实是相当于使用dotnet build,运行这一步相当于运行依赖于框架的应用程序 DLL,比如dotnet MyAppOne.dll

命令取决于生成代码的 dotnet build 命令。 对于此生成的任何要求,例如项目必须首先还原,同样适用于 dotnet run


来源:dotnet run 命令 - .NET CLI | Microsoft Docs

输出文件会写入到默认位置,即 bin/<configuration>/<target>。 例如,如果具有 netcoreapp2.1 应用程序并且运行 dotnet run,则输出置于 bin/Debug/netcoreapp2.1。 将根据需要覆盖文件。 临时文件将置于 obj 目录。

常用命令选项

一般情况下,是在项目根目录运行dotnet run

项目结构

尝试对在dotnet new一节中生成的控制台项目MyAppOne的根目录运行dotnet run。会运行默认的Program.cs,输出Hello World!

项目结构会增加一个bin目录:

.
├── MyAppOne.csproj
├── Program.cs
├── bin
└── obj

bin目录的结构如下:

.
└── Debug
    └── net5.0
        ├── MyAppOne.deps.json
        ├── MyAppOne.dll
        ├── MyAppOne.exe
        ├── MyAppOne.pdb
        ├── MyAppOne.runtimeconfig.dev.json
        ├── MyAppOne.runtimeconfig.json
        └── ref
            └── MyAppOne.dll

为什么执行dotnet run之后的输出文件会在bin/Debug/net 5.0之下,已经在前面dotnet run的选项里讲的很清楚了,就不再赘述。下面讲一下输出文件的每一个文件的作用。

每个文件的作用

dotnet build

生成项目及其所有依赖项,可以类比为编译。

dotnet build [<PROJECT>|<SOLUTION>] [-a|--arch <ARCHITECTURE>]
    [-c|--configuration <CONFIGURATION>] [-f|--framework <FRAMEWORK>]
    [--force] [--interactive] [--no-dependencies] [--no-incremental]
    [--no-restore] [--nologo] [--no-self-contained] [--os <OS>]
    [-o|--output <OUTPUT_DIRECTORY>] [-r|--runtime <RUNTIME_IDENTIFIER>]
    [--self-contained [true|false]] [--source <SOURCE>]
    [-v|--verbosity <LEVEL>] [--version-suffix <VERSION_SUFFIX>]

dotnet build -h|--help

输出文件会写入到默认位置,即 bin/<configuration>/<target>

常用命令选项

Debug vs Release

dotnet rundotnet builddotnet publish中都有一个选项,叫做-c|--configuration <CONFIGURATION>。微软官方对这个选项的解释是:

定义生成配置。 大多数项目的默认配置为 Debug,但你可以覆盖项目中的生成配置设置。

显然,微软的官方解释并不容易理解。其实Debug和Release两种模式是.NET默认的两种模式,默认情况下,Debug模式生成的pdb文件含有全部的断点信息,在进行调试的时候,保存着调试和项目状态信息、有断言、堆栈检查等代码。在Visual Studio里面只有选择Debug模式才会有完整的调试信息,如果选择Release模式进行调试,基本上只能输出出什么错了+错误在哪行当然这只是.NET的默认设置,可以在Visual Studio里面进行自定义的配置。在Visual Studio Code里面,调试默认使用Debug模式。

Release模式并非一无是处,它编译时对应用程序的速度进行优化,使得程序在代码大小和运行速度上都是最优的

下面提供一些互联网上关于这两个模式的讨论:

The Release mode enables optimizations and generates without any debug data, so it is fully optimized. . Lots of your code could be completely removed or rewritten in Release mode. The resulting executable will most likely not match up with your written code. Because of this release mode will run faster than debug mode due to the optimizations.


来源:Difference between a Debug and Release build (net-informations.com)

The most important thing is that in Debug mode there are no optimizations, while in Release mode there are optimizations. This is important because the compiler is very advanced and can do some pretty tricky low-level improving of your code. As a result some lines of your code might get left without any instructions at all, or some might get all mixed up. Step-by-step debugging would be impossible. Also, local variables are often optimized in mysterious ways, so Watches and QuickWatches often don't work because the variable is "optimized away". And there are multitudes of other optimizations too. Try debugging optimized .NET code sometime and you'll see.

Another key difference is that because of this the default Release settings don't bother with generating extensive debug symbol information. That's the .PDB file you might have noticed and it allows the debugger to figure out which assembly instructions corresspond to which line of code, etc.


来源:.net - What is the difference between Debug and Release in Visual Studio? - Stack Overflow

建议按照这两个模式的字面意思来选择,比如说在调试阶段就用Debug模式,调试完毕之后的运行、构建和发布就用Release模式。这样既能保证在调试时能够看到最完整的调试信息,也能保证代码运行、构建和发布速度更快。

项目结构

和运行dotnet run之后的项目结构一致,参见dotnet run项目结构

想要保证编译后的文件能够运行MyAppOne.dllMyAppOne.deps.jsonMyAppOne.runtimeconfig.json不可或缺的。如果觉得build之后生成的文件太多,可以尝试使用.NET 6.0然后参考单文件应用程序 - .NET | Microsoft Docs,但是不建议在build阶段去尝试生成单文件,因为build的本质就是去生成项目及其所有依赖项。如果想要生成单文件,可以在部署阶段(publish)来尝试单文件部署。

dotnet publish

将应用程序及其依赖项发布到文件夹以部署到托管系统。

dotnet publish [<PROJECT>|<SOLUTION>] [-a|--arch <ARCHITECTURE>]
    [-c|--configuration <CONFIGURATION>]
    [-f|--framework <FRAMEWORK>] [--force] [--interactive]
    [--manifest <PATH_TO_MANIFEST_FILE>] [--no-build] [--no-dependencies]
    [--no-restore] [--nologo] [-o|--output <OUTPUT_DIRECTORY>]
    [--os <OS>] [-r|--runtime <RUNTIME_IDENTIFIER>]
    [--self-contained [true|false]]
    [--no-self-contained] [-v|--verbosity <LEVEL>]
    [--version-suffix <VERSION_SUFFIX>]

dotnet publish -h|--help

输出文件默认位置是 bin/<configuration>/<target>/publish

常用命令选项

基本上和dotnet build 的常用命令选项一致,有个比较大的不同就是使用-r|--runtime <RUNTIME_IDENTIFIER>时可以指定self-contained,不需要像dotnet build一样得等到.NET 6.0才能指定self-contained


来源:dotnet publish 命令 - .NET CLI | Microsoft Docs

项目结构

输出文件默认位置是 bin/<configuration>/<target>/publish

默认状态下项目结构和dotnet build项目结构不一样的点有两个,一个是没有了ref文件夹,一个是没有了runtimeconfig.dev.json

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2021/10/17      6:46            416 MyAppOne.deps.json
-a----        2021/10/15     16:01           4608 MyAppOne.dll
-a----        2021/10/15     16:01         125952 MyAppOne.exe
-a----        2021/10/15     16:01           9600 MyAppOne.pdb
-a----        2021/10/17      6:46            147 MyAppOne.runtimeconfig.json

单文件部署和可执行文件

单个文件部署与 Windows 7 不兼容。

有两个好方法:

  1. 修改MSBuild(.csrpoj)文件,然后dotnet publish

    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net5.0</TargetFramework>
        <PublishSingleFile>true</PublishSingleFile>
        <SelfContained>true</SelfContained>
        <RuntimeIdentifier>win-x64</RuntimeIdentifier>
        <PublishReadyToRun>true</PublishReadyToRun>
      </PropertyGroup>
    
    </Project>
    
  2. 完全通过命令行,无需修改MSBuild(.csrpoj)文件

    dotnet publish -r linux-x64 -p:PublishSingleFile=true --self-contained true
    

原理解释

首先,必须指定PublishSingleFile为真,这是生成单个文件的基础。SelfContained为真保证可以独立而不依赖框架,RuntimeIdentifier来指定系统和cpu类型,只有指定了这个,指定SelfContained才有意义

  • --self-contained [true|false]

    .NET 运行时随应用程序一同发布,因此无需在目标计算机上安装运行时。 如果指定了运行时标识符,并且项目是可执行项目(而不是库项目),则默认值为 true。 有关详细信息,请参阅 .NET 应用程序发布使用 .NET CLI 发布 .NET 应用

    如果在未指定 true 或 false 的情况下使用此选项,则默认值为 true。 在这种情况下,请不要紧接在 --self-contained 后放置解决方案或项目参数,因为该位置需要 true 或 false


来源:dotnet publish 命令 - .NET CLI | Microsoft Docs

即使是发布单文件,--self-contained也要根据需求慎重考虑。

dotnet restore

dotnet restore 命令使用 NuGet 还原依赖项以及在 project 文件中指定的特定于项目的工具。 在大多数情况下,不需要显式使用 dotnet restore 命令,因为在运行以下命令时,将会在必要时隐式运行 NuGet 还原:

build vs publish

最开始的时候,这俩的区别是输出的文件能否在另一台机器上运行(is ready to be transferred to another machine to run.)。但是随着.NET框架的发展,build和publish的含义也在发生着变化(其实这要怪微软,不知道从什么时候开始,感觉微软整个公司氛围开始变成说话不算数,朝令夕改了)。

本文无意去讨论在整个漫长的.NET发展周期( .NET Framework、 .NET Core等 )内这两个命令含义的变化,现在是2021年10月17日,目前最近的稳定版是.NET 5.0,所以本文只讨论.NET 5.0中build和publish的区别。

MSBuild

.NET 应用是使用 MSBuild 从源代码中生成的。 项目文件(.csproj、.fsproj 或 .vbproj)指定目标和负责编译、打包和发布代码的关联任务 。 有引用目标和任务的标准集合的 SDK 标识符。 使用这些标识符有助于使项目文件较小且易于使用。

MSBuild进行修改有两个方法,一个是在文件中修改,一个是在命令行中修改。其中在命令行中修改适用于dotnet build -pdotnet publish -p,但不适用于dotnet run。也可以用MSBuild.exe [Switches] [ProjectFile]来进行命令行修改,可以参考MSBuild 命令行参考 - MSBuild | Microsoft Docsdotnet publish 命令 - .NET CLI | Microsoft Docs

dotnet builddotnet publish可以用-p:<NAME>=<VALUE>来定义MSBuild属性,常用的几个属性如下:

注意,.NET 5.0中dotnet build设置SelfContained无效。

关于MSBuild的深度中文解析可以看理解 C# 项目 csproj 文件格式的本质和编译流程 - walterlv

.NET CLI 发布 .NET 应用

.NET 提供了三种发布应用程序的方法。 依赖于框架的部署会生成一个跨平台 .dll 文件,此文件使用本地安装的 .NET 运行时。 依赖于框架的可执行文件会生成一个特定于平台的可执行文件,此文件使用本地安装的 .NET 运行时。 独立式可执行文件会生成一个特定于平台的可执行文件,并包含 .NET 运行时的本地副本。

发布模式SDK 版本命令
依赖框架的部署 2.1 dotnet publish -c Release
  3.1 dotnet publish -c Release -p:UseAppHost=false
  5.0 dotnet publish -c Release -p:UseAppHost=false
依赖于框架的可执行文件 3.1 dotnet publish -c Release -r <RID> --self-contained false dotnet publish -c Release
  5.0 dotnet publish -c Release -r <RID> --self-contained false dotnet publish -c Release
独立部署 2.1 dotnet publish -c Release -r <RID> --self-contained true
  3.1 dotnet publish -c Release -r <RID> --self-contained true
  5.0 dotnet publish -c Release -r <RID> --self-contained true

上述表格来源:使用 .NET CLI 发布应用 - .NET | Microsoft Docs

另外,还可以通过PublishSingleFile来部署成单个可执行文件

参考文档

LICENSE

copyright © 2021 苏月晟,版权所有。

标签:文件,C#,WoW,publish,--,开源,build,dotnet,NET
来源: https://www.cnblogs.com/Leo_wl/p/15796191.html