Distribution med en fil
Genom att paketera alla programberoende filer i en enda binär fil får en programutvecklare det attraktiva alternativet att distribuera och distribuera programmet som en enda fil. Distribution med en fil är tillgänglig för både den ramverksberoende distributionsmodellen och fristående program.
Storleken på den enskilda filen i ett fristående program är stor eftersom den innehåller körnings- och ramverksbiblioteken. I .NET 6 kan du publicera trimmade för att minska den totala storleken på trimkompatibla program. Distributionsalternativet för en enskild fil kan kombineras med publiceringsalternativen ReadyToRun och Trim .
Viktigt!
Om du vill köra en enskild filapp i Windows 7 måste du använda .NET Runtime 6.0.3 eller senare.
Exempelprojektfil
Här är en exempelprojektfil som anger enkel filpublicering:
<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>
Dessa egenskaper har följande funktioner:
PublishSingleFile
. Aktiverar enkel filpublicering. Aktiverar även enstaka filvarningar underdotnet build
.SelfContained
. Avgör om appen är fristående eller ramverksberoende.RuntimeIdentifier
. Anger vilken operativsystem- och CPU-typ du riktar in dig på. Anger<SelfContained>true</SelfContained>
också som standard.
Appar med en fil är alltid os- och arkitekturspecifika. Du måste publicera för varje konfiguration, till exempel Linux x64, Linux Arm64, Windows x64 och så vidare.
Körningskonfigurationsfiler, till exempel *.runtimeconfig.json och *.deps.json, ingår i den enskilda filen.
Publicera en enfilsapp
Publicera ett enda filprogram med hjälp av dotnet-publiceringskommandot.
Lägg till
<PublishSingleFile>true</PublishSingleFile>
i projektfilen.Den här ändringen genererar en enskild filapp vid fristående publicering. Den visar också varningar om enkel filkompatibilitet under kompilering.
<PropertyGroup> <PublishSingleFile>true</PublishSingleFile> </PropertyGroup>
Publicera appen för en specifik körningsidentifierare med hjälp av
dotnet publish -r <RID>
I följande exempel publiceras appen för Windows som ett fristående program med en enda fil.
dotnet publish -r win-x64
I följande exempel publiceras appen för Linux som ett ramverksberoende program med en enda fil.
dotnet publish -r linux-x64 --self-contained false
<PublishSingleFile>
bör anges i projektfilen för att aktivera filanalys under bygget, men det är också möjligt att skicka dessa alternativ som dotnet publish
argument:
dotnet publish -r linux-x64 -p:PublishSingleFile=true --self-contained false
Mer information finns i Publicera .NET Core-appar med .NET CLI.
Undanta filer från att bäddas in
Vissa filer kan uttryckligen undantas från att bäddas in i den enskilda filen genom att ange följande metadata:
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
Om du till exempel vill placera vissa filer i publiceringskatalogen men inte paket dem i filen:
<ItemGroup>
<Content Update="Plugin.dll">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</Content>
</ItemGroup>
Inkludera PDB-filer i paketet
PDB-filen för en sammansättning kan bäddas in i själva sammansättningen () .dll
med hjälp av inställningen nedan. Eftersom symbolerna ingår i sammansättningen är de också en del av programmet:
<DebugType>embedded</DebugType>
Lägg till exempel till följande egenskap i projektfilen för en sammansättning för att bädda in PDB-filen i den sammansättningen:
<PropertyGroup>
<DebugType>embedded</DebugType>
</PropertyGroup>
Övriga beaktanden
Enfilsprogram har alla relaterade PDB-filer tillsammans med programmet, inte paketerade som standard. Om du vill inkludera PDF-filer i sammansättningen för projekt som du skapar anger du DebugType
till embedded
. Se Inkludera PDB-filer i paketet.
Hanterade C++-komponenter passar inte bra för distribution av en enskild fil. Vi rekommenderar att du skriver program i C# eller ett annat icke-hanterat C++-språk för att vara en enda filkompatibel.
Interna bibliotek
Endast hanterade DLL:er paketeras med appen i en enda körbar fil. När appen startar extraheras och läses de hanterade DLL:erna in i minnet, vilket undviker extrahering till en mapp. Med den här metoden bäddas de hanterade binärfilerna in i det enskilda filpaketet, men de interna binärfilerna för själva kärnkörningen är separata filer.
Om du vill bädda in filerna för extrahering och hämta en utdatafil anger du egenskapen IncludeNativeLibrariesForSelfExtract
till true
.
Om du anger IncludeAllContentForSelfExtract
extraheras alla filer, inklusive de hanterade sammansättningarna, innan du kör den körbara filen. Detta kan vara användbart för sällsynta programkompatibilitetsproblem.
Viktigt!
Om extrahering används extraheras filerna till disken innan appen startar:
DOTNET_BUNDLE_EXTRACT_BASE_DIR
Om miljövariabeln är inställd på en sökväg extraheras filerna till en katalog under den sökvägen.- Annars, om de körs på Linux eller macOS, extraheras filerna till en katalog under
$HOME/.net
. - Om de körs i Windows extraheras filerna till en katalog under
%TEMP%/.net
.
För att förhindra manipulering bör dessa kataloger inte skrivas av användare eller tjänster med olika behörigheter. Använd inte /tmp eller /var/tmp på de flesta Linux- och macOS-system.
Kommentar
I vissa Linux-miljöer, till exempel under systemd
, fungerar inte standardextraheringen eftersom $HOME
den inte har definierats. I sådana fall rekommenderar vi att du anger $DOTNET_BUNDLE_EXTRACT_BASE_DIR
explicit.
För systemd
är ett bra alternativ att definiera DOTNET_BUNDLE_EXTRACT_BASE_DIR
i tjänstens enhetsfil som %h/.net
, som expanderas korrekt till $HOME/.net
för kontot som systemd
kör tjänsten.
[Service]
Environment="DOTNET_BUNDLE_EXTRACT_BASE_DIR=%h/.net"
API-inkompatibilitet
Vissa API:er är inte kompatibla med distribution av en enda fil. Program kan kräva ändringar om de använder dessa API:er. Om du använder ett ramverk eller paket från tredje part är det möjligt att de använder något av dessa API:er och behöver ändras. Den vanligaste orsaken till problem är beroende av filsökvägar för filer eller DLL:er som levereras med programmet.
Tabellen nedan innehåller relevant API-information för körningsbiblioteket för enkel filanvändning.
API | Kommentar |
---|---|
Assembly.CodeBase |
Kastar PlatformNotSupportedException. |
Assembly.EscapedCodeBase |
Kastar PlatformNotSupportedException. |
Assembly.GetFile |
Kastar IOException. |
Assembly.GetFiles |
Kastar IOException. |
Assembly.Location |
Returnerar en tom sträng. |
AssemblyName.CodeBase |
Returnerar null . |
AssemblyName.EscapedCodeBase |
Returnerar null . |
Module.FullyQualifiedName |
Returnerar en sträng med värdet <Unknown> för eller genererar ett undantag. |
Marshal.GetHINSTANCE |
Returnerar -1. |
Module.Name |
Returnerar en sträng med värdet <Unknown> . |
Vi har några rekommendationer för att åtgärda vanliga scenarier:
Om du vill komma åt filer bredvid den körbara filen använder du AppContext.BaseDirectory.
Om du vill hitta filnamnet för den körbara filen använder du det första elementet Environment.GetCommandLineArgs()i , eller börjar med .NET 6, använder du filnamnet från ProcessPath.
Om du vill undvika att skicka lösa filer helt bör du överväga att använda inbäddade resurser.
Binärfiler efter bearbetning före paketering
Vissa arbetsflöden kräver efterbearbetning av binärfiler innan paketering. Ett vanligt exempel är signering. Dotnet SDK tillhandahåller MSBuild-tilläggspunkter för att tillåta bearbetning av binärfiler precis före paketering med en fil. De tillgängliga API:erna är:
- Ett mål
PrepareForBundle
som ska anropas föreGenerateSingleFileBundle
- En
<ItemGroup><FilesToBundle /></ItemGroup>
som innehåller alla filer som ska paketeras - En egenskap
AppHostFile
som anger mallen apphost. Efterbearbetningen kanske vill undanta apphost från bearbetning.
Att ansluta till detta innebär att skapa ett mål som ska köras mellan PrepareForBundle
och GenerateSingleFileBundle
.
Överväg följande .NET-projektnodexempel Target
:
<Target Name="MySignedBundledFile" BeforeTargets="GenerateSingleFileBundle" DependsOnTargets="PrepareForBundle">
Det är möjligt att verktyg måste kopiera filer under signeringsprocessen. Det kan inträffa om den ursprungliga filen är ett delat objekt som inte ägs av bygget, till exempel om filen kommer från en NuGet-cache. I så fall förväntas verktyget ändra sökvägen till motsvarande FilesToBundle
objekt så att det pekar på den ändrade kopian.
Komprimera sammansättningar i appar med en fil
Appar med en fil kan skapas med komprimering aktiverat på de inbäddade sammansättningarna. Ange egenskapen EnableCompressionInSingleFile
till true
. Den enda fil som skapas kommer att ha alla inbäddade sammansättningar komprimerade, vilket avsevärt kan minska storleken på den körbara filen.
Komprimering medför en prestandakostnad. Vid programstart måste sammansättningarna dekomprimeras till minnet, vilket tar lite tid. Vi rekommenderar att du mäter både storleksändringen och startkostnaden för att aktivera komprimering innan du använder den. Effekten kan variera avsevärt mellan olika program.
Inspektera en enfilsapp
Appar med en fil kan inspekteras med hjälp av ILSpy-verktyget. Verktyget kan visa alla filer som paketeras i programmet och kan granska innehållet i hanterade sammansättningar.