Wdrażanie pojedynczego pliku
Łączenie wszystkich plików zależnych od aplikacji w jeden plik binarny zapewnia deweloperowi aplikacji atrakcyjną opcję wdrażania i dystrybuowania aplikacji jako pojedynczego pliku. Wdrożenie jednoplikowe jest dostępne zarówno dla modelu wdrażania zależnego od struktury, jak i aplikacji samodzielnie zawartych.
Rozmiar pojedynczego pliku w aplikacji samodzielnej jest duży, ponieważ obejmuje środowisko uruchomieniowe i biblioteki struktury. Na platformie .NET 6 można opublikować przycięte, aby zmniejszyć całkowity rozmiar aplikacji zgodnych z przycinania. Opcja wdrożenia pojedynczego pliku może być połączona z opcjami publikowania ReadyToRun i Trim .
Ważne
Aby uruchomić pojedynczą aplikację plików w systemie Windows 7, musisz użyć środowiska uruchomieniowego .NET Runtime 6.0.3 lub nowszego.
Przykładowy plik projektu
Oto przykładowy plik projektu, który określa publikowanie pojedynczego pliku:
<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>
Te właściwości mają następujące funkcje:
PublishSingleFile
. Umożliwia publikowanie pojedynczego pliku. Włącza również ostrzeżenia dotyczące pojedynczego pliku podczas wykonywaniadotnet build
polecenia .SelfContained
. Określa, czy aplikacja jest zależna od siebie, czy struktury.RuntimeIdentifier
. Określa docelowy typ systemu operacyjnego i procesora CPU.<SelfContained>true</SelfContained>
Ustawia również domyślnie.
Pojedyncze aplikacje plików są zawsze specyficzne dla systemu operacyjnego i architektury. Musisz opublikować dla każdej konfiguracji, takie jak Linux x64, Linux Arm64, Windows x64 itd.
Pliki konfiguracji środowiska uruchomieniowego, takie jak *.runtimeconfig.json i *.deps.json, są uwzględniane w jednym pliku.
Publikowanie aplikacji z jednym plikiem
Publikowanie pojedynczej aplikacji plików przy użyciu polecenia dotnet publish .
Dodaj
<PublishSingleFile>true</PublishSingleFile>
do pliku projektu.Ta zmiana powoduje utworzenie pojedynczej aplikacji plików w ramach samodzielnego publikowania. Wyświetlane są również ostrzeżenia dotyczące zgodności z pojedynczym plikiem podczas kompilacji.
<PropertyGroup> <PublishSingleFile>true</PublishSingleFile> </PropertyGroup>
Publikowanie aplikacji dla określonego identyfikatora środowiska uruchomieniowego przy użyciu polecenia
dotnet publish -r <RID>
Poniższy przykład publikuje aplikację dla systemu Windows jako samodzielną aplikację z pojedynczym plikiem.
dotnet publish -r win-x64
Poniższy przykład publikuje aplikację dla systemu Linux jako aplikację zależną od platformy z pojedynczym plikiem.
dotnet publish -r linux-x64 --self-contained false
<PublishSingleFile>
Należy ustawić w pliku projektu, aby włączyć analizę plików podczas kompilacji, ale istnieje również możliwość przekazania tych opcji jako dotnet publish
argumentów:
dotnet publish -r linux-x64 -p:PublishSingleFile=true --self-contained false
Aby uzyskać więcej informacji, zobacz Publikowanie aplikacji platformy .NET Core za pomocą interfejsu wiersza polecenia platformy .NET.
Wykluczanie plików z osadzania
Niektóre pliki można jawnie wykluczyć z osadowania w jednym pliku, ustawiając następujące metadane:
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
Aby na przykład umieścić niektóre pliki w katalogu publikowania, ale nie umieścić ich w pliku:
<ItemGroup>
<Content Update="Plugin.dll">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</Content>
</ItemGroup>
Dołączanie plików PDB do pakietu
Plik PDB zestawu można osadzić w samym zestawie () .dll
przy użyciu poniższego ustawienia. Ponieważ symbole są częścią zestawu, są one również częścią aplikacji:
<DebugType>embedded</DebugType>
Na przykład dodaj następującą właściwość do pliku projektu zestawu, aby osadzić plik PDB w tym zestawie:
<PropertyGroup>
<DebugType>embedded</DebugType>
</PropertyGroup>
Inne uwagi
Aplikacje z jednym plikiem mają wszystkie powiązane pliki PDB wraz z aplikacją, a nie są domyślnie powiązane. Jeśli chcesz dołączyć pliki PDB do zestawu dla projektów, które tworzysz, ustaw wartość DebugType
embedded
. Zobacz Dołączanie plików PDB wewnątrz pakietu.
Zarządzane składniki języka C++ nie nadają się do wdrożenia pojedynczego pliku. Zalecamy pisanie aplikacji w języku C# lub innym niezarządzanym języku C++, aby były zgodne z pojedynczym plikiem.
Biblioteki natywne
Tylko zarządzane biblioteki DLL są połączone z aplikacją w jeden plik wykonywalny. Po uruchomieniu aplikacji zarządzane biblioteki DLL są wyodrębniane i ładowane w pamięci, co pozwala uniknąć wyodrębniania do folderu. W przypadku tego podejścia zarządzane pliki binarne są osadzone w jednym pakiecie plików, ale pliki binarne natywne samego środowiska uruchomieniowego podstawowego są oddzielnymi plikami.
Aby osadzić te pliki na potrzeby wyodrębniania i pobrać jeden plik wyjściowy, ustaw właściwość IncludeNativeLibrariesForSelfExtract
na true
wartość .
Określenie IncludeAllContentForSelfExtract
wyodrębnia wszystkie pliki, w tym zarządzane zestawy, przed uruchomieniem pliku wykonywalnego. Może to być przydatne w przypadku rzadkich problemów ze zgodnością aplikacji.
Ważne
Jeśli wyodrębnianie jest używane, pliki są wyodrębniane na dysk przed uruchomieniem aplikacji:
- Jeśli zmienna
DOTNET_BUNDLE_EXTRACT_BASE_DIR
środowiskowa jest ustawiona na ścieżkę, pliki są wyodrębniane do katalogu pod tą ścieżką. - W przeciwnym razie w przypadku uruchamiania w systemie Linux lub macOS pliki są wyodrębniane do katalogu w obszarze
$HOME/.net
. - W przypadku uruchamiania w systemie Windows pliki są wyodrębniane do katalogu w obszarze
%TEMP%/.net
.
Aby zapobiec manipulacji, te katalogi nie powinny być zapisywalne przez użytkowników lub usługi z różnymi uprawnieniami. Nie używaj /tmp ani /var/tmp w większości systemów Linux i macOS.
Uwaga
W niektórych środowiskach systemu Linux, takich jak w obszarze systemd
, domyślne wyodrębnianie nie działa, ponieważ $HOME
nie jest zdefiniowane. W takich przypadkach zaleca się jawne ustawienie $DOTNET_BUNDLE_EXTRACT_BASE_DIR
.
W przypadku systemd
programu dobrą alternatywą jest zdefiniowanie DOTNET_BUNDLE_EXTRACT_BASE_DIR
w pliku jednostkowym usługi jako %h/.net
, który rozszerza się poprawnie dla $HOME/.net
konta, na którym systemd
jest uruchomiona usługa.
[Service]
Environment="DOTNET_BUNDLE_EXTRACT_BASE_DIR=%h/.net"
Niezgodność interfejsu API
Niektóre interfejsy API nie są zgodne z wdrożeniem pojedynczego pliku. Aplikacje mogą wymagać modyfikacji, jeśli korzystają z tych interfejsów API. Jeśli używasz struktury lub pakietu innej firmy, możliwe jest, że mogą używać jednego z tych interfejsów API i wymagać modyfikacji. Najczęstszą przyczyną problemów jest zależność od ścieżek plików lub bibliotek DLL dostarczanych z aplikacją.
Poniższa tabela zawiera szczegółowe informacje o interfejsie API biblioteki środowiska uruchomieniowego na potrzeby użycia pojedynczego pliku.
interfejs API | Uwaga |
---|---|
Assembly.CodeBase |
Zgłasza element PlatformNotSupportedException. |
Assembly.EscapedCodeBase |
Zgłasza element PlatformNotSupportedException. |
Assembly.GetFile |
Zgłasza element IOException. |
Assembly.GetFiles |
Zgłasza element IOException. |
Assembly.Location |
Zwraca pusty ciąg. |
AssemblyName.CodeBase |
Zwraca wartość null . |
AssemblyName.EscapedCodeBase |
Zwraca wartość null . |
Module.FullyQualifiedName |
Zwraca ciąg z wartością <Unknown> lub zgłasza wyjątek. |
Marshal.GetHINSTANCE |
Zwraca wartość -1. |
Module.Name |
Zwraca ciąg z wartością <Unknown> . |
Mamy kilka zaleceń dotyczących naprawiania typowych scenariuszy:
Aby uzyskać dostęp do plików obok pliku wykonywalnego, użyj polecenia AppContext.BaseDirectory.
Aby znaleźć nazwę pliku wykonywalnego, użyj pierwszego elementu Environment.GetCommandLineArgs(), lub zaczynając od platformy .NET 6, użyj nazwy pliku z ProcessPath.
Aby uniknąć całkowitego wysyłania luźnych plików, rozważ użycie zasobów osadzonych.
Przetwarzanie plików binarnych po przetworzeniu przed tworzeniem pakietów
Niektóre przepływy pracy wymagają przetwarzania końcowego plików binarnych przed tworzeniem pakietów. Typowym przykładem jest podpisywanie. Zestaw DOTNET SDK udostępnia punkty rozszerzenia MSBuild, aby umożliwić przetwarzanie plików binarnych tuż przed tworzeniem pakietów pojedynczego pliku. Dostępne interfejsy API to:
- Element docelowy
PrepareForBundle
, który będzie wywoływany przedGenerateSingleFileBundle
- Plik
<ItemGroup><FilesToBundle /></ItemGroup>
zawierający wszystkie pliki, które zostaną połączone - Właściwość
AppHostFile
określająca szablon apphost. Przetwarzanie końcowe może chcieć wykluczyć host apphost z przetwarzania.
Aby połączyć się z tym elementem, należy utworzyć obiekt docelowy, który zostanie wykonany między elementami PrepareForBundle
i GenerateSingleFileBundle
.
Rozważmy następujący przykładowy węzeł projektu Target
platformy .NET:
<Target Name="MySignedBundledFile" BeforeTargets="GenerateSingleFileBundle" DependsOnTargets="PrepareForBundle">
Istnieje możliwość, że narzędzia będą musiały kopiować pliki w procesie podpisywania. Może się tak zdarzyć, jeśli oryginalny plik jest elementem udostępnionym, który nie jest własnością kompilacji, na przykład plik pochodzi z pamięci podręcznej NuGet. W takim przypadku oczekuje się, że narzędzie zmodyfikuje ścieżkę odpowiedniego FilesToBundle
elementu, aby wskazywało zmodyfikowaną kopię.
Kompresowanie zestawów w aplikacjach jednoplikowych
Aplikacje z jednym plikiem można tworzyć z włączoną kompresją w zestawach osadzonych. Ustaw właściwość EnableCompressionInSingleFile
na true
. Wygenerowany pojedynczy plik będzie miał skompresowane wszystkie zestawy osadzone, co może znacząco zmniejszyć rozmiar pliku wykonywalnego.
Kompresja wiąże się z kosztem wydajności. Po uruchomieniu aplikacji zestawy muszą zostać zdekompresowane do pamięci, co zajmuje trochę czasu. Zalecamy mierzenie zarówno zmiany rozmiaru, jak i kosztu uruchamiania włączania kompresji przed jego użyciem. Wpływ może się znacznie różnić między różnymi aplikacjami.
Inspekcja aplikacji z jednym plikiem
Aplikacje z pojedynczymi plikami można sprawdzić przy użyciu narzędzia ILSpy. Narzędzie może wyświetlić wszystkie pliki dołączone do aplikacji i sprawdzić zawartość zarządzanych zestawów.