• .NetCore 3 单文件发布详解


    .NetCore可以将发布时产生的所有零碎文件直接打包成一个单独的运行文件相信大家都已经知道了,但在发布过程还有一些小技巧,我们今天就来聊一聊。

    1. 入门

    我们可以通过命令行将项目发布为单个文件:

    dotnet publish -c Release -r win10-x64 -o release/win10-x64 /p:PublishSingleFile=true /p:PublishTrimmed=true

    也可以通过在项目配置文件中的参数来实现:

    <PropertyGroup>
        <PublishSingleFile>true</PublishSingleFile>
        <PublishTrimmed>true</PublishTrimmed>
    </PropertyGroup>    
    • 命令行参数说明
    参数说明备注
    --no-self-contained 不包含runtime 用户需自己安装runtime
    -r 目标平台 win-x64, osx-x64, linux-x64 RID参考
    -c 发布类型 Debug, Release
    -o 程序发布目录 -
    PublishSingleFile 发布为单个文件 true, false
    PublishTrimmed 去除未引用对象 true false


    PublishTrimmed参数可以有效减少发布文件的体积
    --no-self-contained可减少约30M的程序体积,但不能与PublishTrimmed参数同时使用

    2. 进阶

    单文件非常轻松的就发布出来了,但还没过30秒,一般都会发出类似这样的嚎叫:"我去,怎么启动失败?文件加载不了?"

    大多数情况是因为非程序文件没有被一起发布,别急,我们继续聊....

    2.1 修改元数据

    我们可以显式的排除一些文件被打包,通过为项目配置文件添加参数

    <ExcludeFromSingleFile>true</ExcludeFromSingleFile>

    例如,要将某些文件放在发布目录中,但不将它们捆绑到单文件中:

    <ItemGroup>
        <Content Update="*.xml">
          <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
          <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
        </Content>
      </ItemGroup>

    或者像这样复制整个目录

    <ItemGroup>
        <None Update="Assetslang*">
          <Link>lang\%(Filename)%(Extension)</Link>
          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
          <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
        </None>
      </ItemGroup>

    2.2 修改代码

    但仅这样是不够的,因为单文件是在沙箱中运行,所以需要在修改一下代码让它从程序所在目录调用文件,比如这样

    #if DEBUG
      //debug模式调用路径
      string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.json");
    #else
      //release调用路径
      string filePath = Path.Combine(Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName), "config.json");
    #endif
    LoadFile(filePath)

    这样就能取到原来的文件了,不过既然都说到这了,我们就顺便说说.NetCore调用目录函数之间的区别

    2.3 目录区别

    //模块启动位置(非单文件模式时主程序调用为dotnet所在位置)
    Console.WriteLine("StartDir:" + Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName));
    
    //程序启动位置(单文件模式时是虚拟容器内位置)
    Console.WriteLine("AppBaseDir:" + AppContext.BaseDirectory);
    Console.WriteLine("AppBaseDir:" + AppDomain.CurrentDomain.SetupInformation.ApplicationBase);
    Console.WriteLine("AppBaseDir:" + AppDomain.CurrentDomain.BaseDirectory);
    
     //程序当前目录,单文件模式时是用户目录,VSCode运行时为项目目录(不推荐使用)
    Console.WriteLine("CurrentDirectory:" + Environment.CurrentDirectory);
    //同上
    Console.WriteLine(Directory.GetCurrentDirectory());
    
    //程序所在的硬盘根目录
    Console.WriteLine("RootDir:" + Directory.GetDirectoryRoot(
    Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory)
    ));
    
    //用户目录(~/)
    Console.WriteLine("UserProfile:"+Environment.GetFolderPath(Environment.SpecialFolder.UserProfile));
    
    //桌面目录(~/Desktop) 
    Console.WriteLine("DesktopDirectory:"+Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory));
    
    //系统目录(/System)
    Console.WriteLine("SystemDirectory:"+Environment.SystemDirectory);
    
    //程序数据目录(~/.config)
    Console.WriteLine("ApplicationData:"+Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
    2.4 符号文件(可选)

    默认情况下,符号文件不会嵌入到单文件中,而是作为单独的文件保留在发布目录中(如 .pdb .ni.pdb app .guid.map),设置以下属性可将符号文件包含在单文件中。


    <PropertyGroup>
        <IncludeSymbolsInSingleFile>true</IncludeSymbolsInSingleFile>
    </PropertyGroup>
  • 相关阅读:
    书:《必然》
    书:《经济学通识》
    书:《小岛经济学》
    书:《未来简史》
    书:《腾讯传》
    书:《把时间当做朋友》
    《激荡十年》七、玲珑初开、百子待落—2013
    【转】关于大型网站技术演进的思考(十一)--网站静态化处理—动静分离策略(3)
    【转】关于大型网站技术演进的思考(十)--网站静态化处理—动静整合方案(2)
    【转】关于大型网站技术演进的思考(九)--网站静态化处理--总述(1)
  • 原文地址:https://www.cnblogs.com/IIXS/p/13273382.html
Copyright © 2020-2023  润新知