将 SmartAssembly 与单文件可执行文件一起使用 (.NET Core 6)
.NET Core 6引入了创建单文件可执行文件的功能。这只允许分发一个应用程序文件,因为所有配置和依赖项都包含在二进制文件本身中。
该功能为依赖项嵌入提供了一种本机方法,这在发布生成数百个程序集的独立应用程序时最有益。它可用于依赖于框架或自包含的应用程序,但在这两种情况下都需要设置运行时标识符以针对特定环境和位数。
开始
首先,让我们看看发布 .NET Core 应用程序的常规过程是什么样的。
假设我们有一个名为 ConsoleApp 的 .NET Core 6 应用程序,由以下项目文件定义:
- <Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <OutputType>Exe</OutputType>
- <TargetFramework>netcoreapp6</TargetFramework>
- </PropertyGroup>
- </Project>
要发布此应用程序,我们将使用以下命令:
- dotnet publish .\ConsoleApp.csproj -c Release -r win-x64
上面的命令将在“发布”模式下构建应用程序,然后发布为自包含并面向 Windows 64 位系统。所有依赖项(包括 .NET Core 框架程序集)和配置都将复制到已发布的目录中。
发布完成后,转到输出目录(对于上面的应用程序,这将是 \ConsoleApp\bin\Release\netcoreapp6\win-x64\publish\)。注意目录中存在多少个文件。
发布独立 .NET Core 应用程序的过程可以可视化如下:
使用单文件可执行文件
现在,让我们将应用程序发布为单个文件。我们需要做的就是添加一个值设置为 true 的 PublishSingleFile 属性。
- <Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <OutputType>Exe</OutputType>
- <TargetFramework>netcoreapp6</TargetFramework>
- <PublishSingleFile>true</PublishSingleFile> <!-- add this line -->
- </PropertyGroup>
- </Project>
让我们再次发出发布命令:
- dotnet publish .\ConsoleApp.csproj -c Release -r win-x64
完成此过程后,导航到已发布的目录(上述应用的 \ConsoleApp\bin\Release\netcoreapp6\win-x64\publish\)。您应该只看到 1 个.exe文件和一个 .pdb 文件(可选)。
让我们看看启用单文件后发布过程有何变化:
集成智能装配
对于最后一步,让我们在程序集捆绑到单文件可执行文件之前保护它。
SmartAssembly 将在生成应用程序之后执行,但在发布并捆绑到单个文件之前执行。如下图所示:
步骤 1:创建智能程序集项目
- 打开智能装配。
- 单击“新建项目”。
- 单击“浏览程序集”。
- 导航到应用程序的输出目录,选择适当的程序集(对于上面的应用程序,它将是:\ConsoleApp\bin\Release\netcoreapp6\win-x64\ConsoleApp.dll)并打开。
- 单击设置目的地。
- 导航到应用程序的 \obj\ 目录(对于上面的应用程序,它将是:\ConsoleApp\obj\Release\netcoreapp6\win-x64\ConsoleApp.dll)并保存。如果文件已存在,请单击“是”进行覆盖。
- 根据需要配置项目。启用应用程序可能需要的任何保护。
- 单击保存以保存项目。建议将项目保存在与Visual Studio的项目文件相同的位置,名称相同(对于上面的应用,它将是:\ConsoleApp\ConsoleApp.saproj)。
保护单文件程序集时,不应使用“依赖项合并”和“依赖项嵌入”。合并或嵌入程序集可能会导致意外行为,不建议用于此类应用程序。
步骤 2:将智能程序集集成到发布过程中
- 在 Visual Studio 中打开应用程序的项目。
- 右键单击项目名称,然后选择“管理 NuGet 包...”
- 切换到浏览选项卡。
- 键入 RedGate.SmartAssembly.MSBuild,然后单击它旁边的安装。
就是这样!执行上述步骤后,项目文件应如下所示:
- <Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <OutputType>Exe</OutputType>
- <TargetFramework>netcoreapp6</TargetFramework>
- <PublishSingleFile>true</PublishSingleFile>
- </PropertyGroup>
- <ItemGroup>
- <PackageReference Include="RedGate.SmartAssembly.MSBuild" Version="8.1.2.4975">
- <PrivateAssets>all</PrivateAssets>
- <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
- </PackageReference>
- </ItemGroup>
- </Project>
现在让我们再次发出发布命令:
- dotnet publish .\ConsoleApp.csproj -c Release -r win-x64
如果要运行同一项目的多个连续生成,则应在每次生成之前或之后清理项目。由于 SmartAssembly 将程序集模糊处理到 \obj\ 目录中,因此下次生成命令可能会选取经过模糊处理的版本,从而导致双重模糊处理和其他意外结果。
要清理项目,请手动删除 \obj\ 目录或发出以下命令(使用用于发布的相同配置和运行时标识符):
dotnet clean .\ConsoleApp.csproj -c Release -r win-x64
如果一切顺利,您应该会在命令行中看到其他输出消息,确认 SmartAssembly 已成功保护您的应用程序(为清楚起见,缩短了路径):
Microsoft (R) Build Engine version 16.5.0+d4cbfca49 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.
Restore completed in 206.38 ms for C:\[..]\ConsoleApp\ConsoleApp.csproj.
ConsoleApp -> C:\[..]\ConsoleApp\bin\Release\netcoreapp6\win-x64\ConsoleApp.dll
Executing SmartAssembly from: C:\PROGRA~1\Red Gate\SmartAssembly 8\SmartAssembly.com
Using project: C:\[..]\ConsoleApp\ConsoleApp.saproj
SmartAssembly v8.1.2.4975 Personal
Copyright c Red Gate Software Ltd 2005-2020
Loading project C:\[..]\ConsoleApp\ConsoleApp.saproj
Input=C:\[..]\ConsoleApp\bin\Release\netcoreapp3.1\win-x64\ConsoleApp.dll
Loading...
Starting...
Analyzing...
Preparing...
Creating assembly...
Copying additional files...
OK
ConsoleApp -> C:\[..]\ConsoleApp\bin\Release\netcoreapp3.1\win-x64\publish\