Déploiement à fichier unique
Le regroupement de tous les fichiers dépendants de l’application dans un seul fichier binaire offre aux développeurs d’applications l’option intéressante de déployer et de distribuer l’application sous la forme d’un fichier unique. Le déploiement d’un fichier unique est disponible à la fois pour le modèle de déploiement dépendant de l’infrastructure et pour les applications autonomes.
La taille du fichier unique dans une application autonome est importante, car elle inclut le runtime et les bibliothèques d’infrastructure. Dans .NET 6, vous pouvez publier découpé pour réduire la taille totale des applications compatibles avec le découpage. L’option de déploiement de fichier unique peut être combinée avec les options de publication ReadyToRun et Trim.
Important
Pour exécuter une application à fichier unique sur Windows 7, vous devez utiliser le runtime .NET 6.0.3 ou version ultérieure.
Exemple de fichier projet
Voici un exemple de fichier projet qui spécifie la publication à fichier unique :
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>
</Project>
Ces propriétés ont les fonctions suivantes :
PublishSingleFile
. Active la publication de fichiers uniques. Active également les avertissements de fichier unique pendantdotnet build
.SelfContained
. Détermine si l’application est autonome ou dépendante de l’infrastructure.RuntimeIdentifier
. Spécifie le type de système d’exploitation et de processeur que vous ciblez. Définit également<SelfContained>true</SelfContained>
par défaut.
Les applications à fichier unique sont toujours spécifiques au système d’exploitation et à l’architecture. Vous devez publier pour chaque configuration, par exemple Linux x64, Linux Arm64, Windows x64, etc.
Les fichiers de configuration du runtime, tels que *.runtimeconfig.json et *.deps.json, sont inclus dans le fichier unique.
Publier une application à fichier unique
Publiez une application de fichier unique à l’aide de la commande dotnet publish.
Ajoutez
<PublishSingleFile>true</PublishSingleFile>
à votre fichier projet.Cette modification génère une application à fichier unique sur la publication autonome. Cela affiche également des avertissements de compatibilité à fichier unique pendant la génération.
<PropertyGroup> <PublishSingleFile>true</PublishSingleFile> </PropertyGroup>
Publiez l’application pour un identificateur d’exécution spécifique à l’aide de
dotnet publish -r <RID>
L’exemple suivant publie l’application pour Windows en tant qu’application à fichier unique autonome.
dotnet publish -r win-x64
L’exemple suivant publie l’application pour Linux en tant qu’application à fichier unique dépendante de l’infrastructure.
dotnet publish -r linux-x64 --self-contained false
<PublishSingleFile>
doit être défini dans le fichier projet pour activer l’analyse de fichier pendant la génération, mais il est également possible de passer ces options en tant qu’arguments dotnet publish
:
dotnet publish -r linux-x64 -p:PublishSingleFile=true --self-contained false
Pour plus d’informations, consultez Publier des applications .NET Core avec CLI .NET.
Exclure des fichiers de l’incorporation
Certains fichiers peuvent être explicitement exclus de l’incorporation dans le fichier unique en définissant les métadonnées suivantes :
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
Par exemple, pour placer certains fichiers dans le répertoire de publication sans les regrouper dans le fichier :
<ItemGroup>
<Content Update="Plugin.dll">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</Content>
</ItemGroup>
Inclure des fichiers PDB dans le pack
Le fichier PDB d’un assembly peut être incorporé dans l’assembly lui-même (le .dll
) à l’aide du paramètre ci-dessous. Étant donné que les symboles font partie de l’assembly, ils font également partie de l’application :
<DebugType>embedded</DebugType>
Par exemple, ajoutez la propriété suivante au fichier projet d’un assembly pour incorporer le fichier PDB à cet assembly :
<PropertyGroup>
<DebugType>embedded</DebugType>
</PropertyGroup>
Autres considérations
Les applications à fichier unique ont tous les fichiers PDB associés en même temps que l’application, et non groupés par défaut. Si vous souhaitez inclure des fichiers PDF à l’intérieur de l’assembly pour les projets que vous générez, définissez la valeur DebugType
sur embedded
. Consultez Inclure des fichiers PDB à l’intérieur de l’offre groupée.
Les composants C++ managés ne conviennent pas parfaitement au déploiement d’un fichier unique. Nous vous recommandons d’écrire des applications en C# ou dans un autre langage C++ non managé pour qu’elles soient compatibles avec un fichier unique.
Bibliothèques natives
Seules les bibliothèque de liens dynamiques (DLL) managées sont regroupées avec l’application dans un seul fichier exécutable. Lorsque l’application démarre, les DLL managées sont extraites et chargées en mémoire, ce qui évite l’extraction dans un dossier. Avec cette approche, les fichiers binaires managés sont incorporés dans le pack à fichier unique, mais les fichiers binaires natifs du runtime principal lui-même sont des fichiers distincts.
Pour incorporer ces fichiers pour l’extraction et obtenir un fichier de sortie, définissez la propriété IncludeNativeLibrariesForSelfExtract
sur true
.
La spécification de IncludeAllContentForSelfExtract
extrait tous les fichiers, y compris les assemblys managés, avant d’exécuter l’exécutable. Cela peut être utile pour les rares problèmes de compatibilité d’application.
Important
Si l’extraction est utilisée, les fichiers sont extraits sur le disque avant le démarrage de l’application :
- Si la variable d’environnement
DOTNET_BUNDLE_EXTRACT_BASE_DIR
est définie sur un chemin, les fichiers sont extraits dans un répertoire sous ce chemin. - Sinon, en cas d’exécution sur Linux ou macOS, les fichiers sont extraits dans un répertoire sous
$HOME/.net
. - En cas d’exécution sur Windows, les fichiers sont extraits dans un répertoire sous
%TEMP%/.net
.
Pour empêcher la falsification, ces répertoires ne doivent pas être accessibles en écriture par les utilisateurs ou les services disposant de privilèges différents. N’utilisez pas /tmp ou /var/tmp sur la plupart des systèmes Linux et macOS.
Notes
Dans certains environnements Linux, tels que sous systemd
, l’extraction par défaut ne fonctionne pas, car $HOME
n’est pas défini. Dans ce cas, nous vous recommandons de définir $DOTNET_BUNDLE_EXTRACT_BASE_DIR
explicitement.
Pour systemd
, une bonne alternative consiste à définir DOTNET_BUNDLE_EXTRACT_BASE_DIR
dans le fichier d’unité de votre service en tant que %h/.net
, que systemd
étend correctement à $HOME/.net
pour le compte exécutant le service.
[Service]
Environment="DOTNET_BUNDLE_EXTRACT_BASE_DIR=%h/.net"
Incompatibilité d’API
Certaines API ne sont pas compatibles avec le déploiement de fichiers uniques. Les applications peuvent nécessiter une modification si elles utilisent ces API. Si vous utilisez une infrastructure ou un package tiers, il est possible qu’ils utilisent l’une de ces API et nécessitent une modification. La cause la plus courante des problèmes est la dépendance vis-à-vis des chemins d’accès aux fichiers ou DLL fournis avec l’application.
Le tableau ci-dessous contient les détails pertinents de l’API de la bibliothèque de runtime pour l’utilisation d’un fichier unique.
API | Notes |
---|---|
Assembly.CodeBase |
Lève PlatformNotSupportedException. |
Assembly.EscapedCodeBase |
Lève PlatformNotSupportedException. |
Assembly.GetFile |
Lève IOException. |
Assembly.GetFiles |
Lève IOException. |
Assembly.Location |
Retourne une chaîne vide. |
AssemblyName.CodeBase |
Retourne null . |
AssemblyName.EscapedCodeBase |
Retourne null . |
Module.FullyQualifiedName |
Retourne une chaîne avec la valeur <Unknown> ou lève une exception. |
Marshal.GetHINSTANCE |
Retourne -1. |
Module.Name |
Retourne une chaîne avec la valeur <Unknown> . |
Nous avons quelques recommandations pour résoudre les scénarios courants :
Pour accéder aux fichiers à côté du fichier exécutable, utilisez AppContext.BaseDirectory.
Pour rechercher le nom de fichier de l’exécutable, utilisez le premier élément de Environment.GetCommandLineArgs(), ou à partir de .NET 6, utilisez le nom de fichier de ProcessPath.
Pour éviter d’expédier entièrement des fichiers libres, envisagez d’utiliser des ressources incorporées.
Fichiers binaires de post-traitement avant regroupement
Certains workflows nécessitent un post-traitement des fichiers binaires avant le regroupement. Un exemple courant est la signature. Le SDK dotnet fournit des points d’extension MSBuild pour permettre le traitement des fichiers binaires juste avant le regroupement à fichier unique. Les API disponibles sont les suivantes :
- Un
PrepareForBundle
cible qui est appelé avantGenerateSingleFileBundle
- Un
<ItemGroup><FilesToBundle /></ItemGroup>
contenant tous les fichiers qui sont regroupés - Une propriété
AppHostFile
qui spécifie le modèle d’apphost. Le post-traitement peut vouloir exclure l’apphost du traitement.
Pour mettre en place cette procédure, il est nécessaire de créer une cible destinée à être exécutée entre PrepareForBundle
et GenerateSingleFileBundle
.
Prenons l’exemple de nœud Target
de projet .NET suivant :
<Target Name="MySignedBundledFile" BeforeTargets="GenerateSingleFileBundle" DependsOnTargets="PrepareForBundle">
Il est possible que les outils doivent copier des fichiers lors de la signature. Cela peut se produire si le fichier d’origine est un élément partagé qui n’appartient pas à la build, par exemple, si le fichier provient d’un cache NuGet. Dans ce cas, l’outil est censé modifier le chemin de l’élément FilesToBundle
correspondant pour qu’il pointe vers la copie modifiée.
Compresser les assemblys dans des applications à fichier unique
Les applications à fichier unique peuvent être créées avec la compression activée sur les assemblys incorporés. Définissez la propriété EnableCompressionInSingleFile
sur true
. Le fichier unique produit aura tous les assemblys incorporés compressés, ce qui peut réduire considérablement la taille de l’exécutable.
La compression est accompagnée d’un coût de performance. Au démarrage de l’application, les assemblys doivent être décompressés en mémoire, ce qui prend un certain temps. Nous vous recommandons de mesurer à la fois le changement de taille et le coût de démarrage de l’activation de la compression avant de l’utiliser. L’impact peut varier considérablement entre différentes applications.
Inspecter une application à fichier unique
Les applications à fichier unique peuvent être inspectées à l’aide de l’outil ILSpy. L’outil peut afficher tous les fichiers regroupés dans l’application et inspecter le contenu des assemblys managés.