zoukankan      html  css  js  c++  java
  • .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>
  • 相关阅读:
    Oracle常用命令大全(很有用,做笔记)
    表格驱动编程在代码中的应用
    mac 利用svn下载远程代码出现Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo.
    FAILURE: Build failed with an exception.
    There is an internal error in the React performance measurement code.Did not expect componentDidMount timer to start while render timer is still in progress for another instance
    react native TypeError network request failed
    Android向系统相册中插入图片,相册中会出现两张 一样的图片(只是图片大小不一致)
    react-native Unrecognized font family ‘Lonicons’;
    react-native SyntaxError xxxxx/xx.js:Unexpected token (23:24)
    Application MyTest has not been registered. This is either due to a require() error during initialization or failure to call AppRegistry.registerComponent.
  • 原文地址:https://www.cnblogs.com/IIXS/p/13273382.html
Copyright © 2011-2022 走看看