Bagikan melalui


Penyebaran file tunggal

Menggabungkan semua file yang bergantung pada aplikasi ke dalam satu biner menyediakan pengembang aplikasi dengan opsi menarik untuk menyebarkan dan mendistribusikan aplikasi sebagai satu file. Penyebaran file tunggal tersedia untuk model penyebaran yang bergantung pada kerangka kerja dan aplikasi mandiri.

Ukuran file tunggal dalam aplikasi mandiri besar karena mencakup runtime dan pustaka kerangka kerja. Di .NET 6, Anda dapat menerbitkan yang dipangkas untuk mengurangi ukuran total aplikasi yang kompatibel dengan pemangkasan. Opsi penyebaran file tunggal dapat dikombinasikan dengan opsi penerbitan ReadyToRun dan Trim .

Penting

Untuk menjalankan aplikasi file tunggal di Windows 7, Anda harus menggunakan .NET Runtime 6.0.3 atau yang lebih baru.

Contoh file proyek

Berikut adalah contoh file proyek yang menentukan penerbitan file tunggal:

<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>

Properti ini memiliki fungsi berikut:

  • PublishSingleFile. Mengaktifkan penerbitan file tunggal. Juga mengaktifkan peringatan file tunggal selama dotnet build.
  • SelfContained. Menentukan apakah aplikasi mandiri atau bergantung pada kerangka kerja.
  • RuntimeIdentifier. Menentukan jenis OS dan CPU yang Anda targetkan. Juga diatur <SelfContained>true</SelfContained> secara default.

Aplikasi file tunggal selalu OS dan arsitektur spesifik. Anda perlu menerbitkan untuk setiap konfigurasi, seperti Linux x64, Linux Arm64, Windows x64, dan sebagainya.

File konfigurasi runtime, seperti *.runtimeconfig.json dan *.deps.json, disertakan dalam satu file.

Menerbitkan aplikasi file tunggal

Terbitkan aplikasi file tunggal menggunakan perintah terbitkan dotnet.

  1. Tambahkan <PublishSingleFile>true</PublishSingleFile> ke file proyek Anda.

    Perubahan ini menghasilkan aplikasi file tunggal pada penerbitan mandiri. Ini juga menunjukkan peringatan kompatibilitas file tunggal selama build.

    <PropertyGroup>
        <PublishSingleFile>true</PublishSingleFile>
    </PropertyGroup>
    
  2. Menerbitkan aplikasi untuk pengidentifikasi runtime tertentu menggunakan dotnet publish -r <RID>

    Contoh berikut menerbitkan aplikasi untuk Windows sebagai aplikasi file tunggal mandiri.

    dotnet publish -r win-x64

    Contoh berikut menerbitkan aplikasi untuk Linux sebagai aplikasi file tunggal dependen kerangka kerja.

    dotnet publish -r linux-x64 --self-contained false

<PublishSingleFile> harus diatur dalam file proyek untuk mengaktifkan analisis file selama build, tetapi juga dimungkinkan untuk meneruskan opsi ini sebagai dotnet publish argumen:

dotnet publish -r linux-x64 -p:PublishSingleFile=true --self-contained false

Untuk informasi selengkapnya, lihat Menerbitkan aplikasi .NET Core dengan .NET CLI.

Mengecualikan file agar tidak disematkan

File tertentu dapat secara eksplisit dikecualikan agar tidak disematkan dalam satu file dengan mengatur metadata berikut:

<ExcludeFromSingleFile>true</ExcludeFromSingleFile>

Misalnya, untuk menempatkan beberapa file di direktori publikasi tetapi tidak memampatkannya dalam file:

<ItemGroup>
  <Content Update="Plugin.dll">
    <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
    <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
  </Content>
</ItemGroup>

Sertakan file PDB di dalam bundel

File PDB untuk rakitan dapat disematkan ke dalam rakitan itu .dllsendiri () menggunakan pengaturan di bawah ini. Karena simbol adalah bagian dari rakitan, simbol tersebut juga merupakan bagian dari aplikasi:

<DebugType>embedded</DebugType>

Misalnya, tambahkan properti berikut ke file proyek perakitan untuk menyematkan file PDB ke rakitan tersebut:

<PropertyGroup>
  <DebugType>embedded</DebugType>
</PropertyGroup>

Pertimbangan lain

Aplikasi file tunggal memiliki semua file PDB terkait bersama aplikasi, tidak dibundel secara default. Jika Anda ingin menyertakan PDB di dalam rakitan untuk proyek yang Anda bangun, atur DebugType ke embedded. Lihat Menyertakan file PDB di dalam bundel.

Komponen C++ terkelola tidak cocok untuk penyebaran file tunggal. Kami menyarankan agar Anda menulis aplikasi dalam C# atau bahasa C++ lain yang tidak dikelola agar kompatibel dengan satu file.

Pustaka asli

Hanya DLL terkelola yang dibundel dengan aplikasi ke dalam satu file yang dapat dieksekusi. Saat aplikasi dimulai, DLL terkelola diekstrak dan dimuat dalam memori, menghindari ekstraksi ke folder. Dengan pendekatan ini, biner terkelola disematkan dalam bundel file tunggal, tetapi biner asli dari runtime inti itu sendiri adalah file terpisah.

Untuk menyematkan file tersebut untuk ekstraksi dan mendapatkan satu file output, atur properti IncludeNativeLibrariesForSelfExtract ke true.

Menentukan IncludeAllContentForSelfExtract ekstrak semua file, termasuk rakitan terkelola, sebelum menjalankan executable. Ini mungkin berguna untuk masalah kompatibilitas aplikasi yang jarang terjadi.

Penting

Jika ekstraksi digunakan, file diekstrak ke disk sebelum aplikasi dimulai:

  • DOTNET_BUNDLE_EXTRACT_BASE_DIR Jika variabel lingkungan diatur ke jalur, file diekstrak ke direktori di bawah jalur tersebut.
  • Jika tidak, jika berjalan di Linux atau macOS, file diekstrak ke direktori di bawah $HOME/.net.
  • Jika berjalan di Windows, file diekstrak ke direktori di bawah %TEMP%/.net.

Untuk mencegah perubahan, direktori ini tidak boleh dapat ditulis oleh pengguna atau layanan dengan hak istimewa yang berbeda. Jangan gunakan /tmp atau /var/tmp pada sebagian besar sistem Linux dan macOS.

Catatan

Di beberapa lingkungan Linux, seperti di bawah systemd, ekstraksi default tidak berfungsi karena $HOME tidak ditentukan. Dalam kasus seperti itu, disarankan agar Anda menetapkan $DOTNET_BUNDLE_EXTRACT_BASE_DIR secara eksplisit.

Untuk systemd, alternatif yang baik adalah menentukan DOTNET_BUNDLE_EXTRACT_BASE_DIR dalam file unit layanan Anda sebagai %h/.net, yang systemd diperluas dengan benar untuk $HOME/.net akun yang menjalankan layanan.

[Service]
Environment="DOTNET_BUNDLE_EXTRACT_BASE_DIR=%h/.net"

Ketidaksesuaian API

Beberapa API tidak kompatibel dengan penyebaran file tunggal. Aplikasi mungkin memerlukan modifikasi jika menggunakan API ini. Jika Anda menggunakan kerangka kerja atau paket pihak ketiga, ada kemungkinan mereka mungkin menggunakan salah satu API ini dan memerlukan modifikasi. Penyebab masalah yang paling umum adalah ketergantungan pada jalur file untuk file atau DLL yang dikirim dengan aplikasi.

Tabel di bawah ini memiliki detail API pustaka runtime yang relevan untuk penggunaan file tunggal.

API Catatan
Assembly.CodeBase Melemparkan PlatformNotSupportedException.
Assembly.EscapedCodeBase Melemparkan PlatformNotSupportedException.
Assembly.GetFile Melemparkan IOException.
Assembly.GetFiles Melemparkan IOException.
Assembly.Location Mengembalikan string kosong.
AssemblyName.CodeBase Menampilkan null.
AssemblyName.EscapedCodeBase Menampilkan null.
Module.FullyQualifiedName Mengembalikan string dengan nilai <Unknown> atau melempar pengecualian.
Marshal.GetHINSTANCE Mengembalikan -1.
Module.Name Mengembalikan string dengan nilai <Unknown>.

Kami memiliki beberapa rekomendasi untuk memperbaiki skenario umum:

Biner pasca-pemrosesan sebelum bundling

Beberapa alur kerja memerlukan pasca-pemrosesan biner sebelum dibundel. Contoh umumnya adalah penandatanganan. Dotnet SDK menyediakan titik ekstensi MSBuild untuk memungkinkan pemrosesan biner tepat sebelum bundel file tunggal. API yang tersedia adalah:

  • Target PrepareForBundle yang akan dipanggil sebelumnya GenerateSingleFileBundle
  • Berisi <ItemGroup><FilesToBundle /></ItemGroup> semua file yang akan dibundel
  • Properti AppHostFile yang akan menentukan templat apphost. Pasca-pemrosesan mungkin ingin mengecualikan apphost dari pemrosesan.

Untuk menyambungkan ke dalam ini melibatkan pembuatan target yang akan dijalankan antara PrepareForBundle dan GenerateSingleFileBundle.

Pertimbangkan contoh node proyek Target .NET berikut:

<Target Name="MySignedBundledFile" BeforeTargets="GenerateSingleFileBundle" DependsOnTargets="PrepareForBundle">

Ada kemungkinan bahwa alat perlu menyalin file dalam proses penandatanganan. Itu bisa terjadi jika file asli adalah item bersama yang tidak dimiliki oleh build, misalnya, file berasal dari cache NuGet. Dalam kasus seperti itu, diharapkan alat akan memodifikasi jalur item yang FilesToBundle sesuai untuk menunjuk ke salinan yang dimodifikasi.

Memadatkan rakitan dalam aplikasi file tunggal

Aplikasi file tunggal dapat dibuat dengan pemadatan diaktifkan pada rakitan yang disematkan. Atur properti EnableCompressionInSingleFile ke true. File tunggal yang dihasilkan akan memiliki semua rakitan yang disematkan terkompresi, yang dapat secara signifikan mengurangi ukuran yang dapat dieksekusi.

Kompresi dilengkapi dengan biaya performa. Pada awal aplikasi, rakitan harus didekompresi ke dalam memori, yang membutuhkan waktu. Kami menyarankan agar Anda mengukur perubahan ukuran dan biaya startup untuk mengaktifkan kompresi sebelum menggunakannya. Dampaknya dapat bervariasi secara signifikan antara aplikasi yang berbeda.

Memeriksa aplikasi file tunggal

Aplikasi file tunggal dapat diperiksa menggunakan alat ILSpy. Alat ini dapat menunjukkan semua file yang dibundel ke dalam aplikasi dan dapat memeriksa konten rakitan terkelola.

Lihat juga