Tek dosyalı dağıtım

Uygulamaya bağımlı tüm dosyaların tek bir ikili dosyaya dönüştürülmesi, uygulama geliştiricisine uygulamayı tek bir dosya olarak dağıtmak ve dağıtmak için cazip bir seçenek sunar. Tek dosyalı dağıtım hem çerçeveye bağımlı dağıtım modeli hem de bağımsız uygulamalar için kullanılabilir.

Çalışma zamanını ve çerçeve kitaplıklarını içerdiğinden, bağımsız bir uygulamadaki tek dosyanın boyutu büyüktür. .NET 6'da, kırpma uyumlu uygulamaların toplam boyutunu azaltmak için kırpılmış olarak yayımlayabilirsiniz. Tek dosya dağıtım seçeneği ReadyToRun ve Kırp yayımlama seçenekleriyle birleştirilebilir.

Önemli

Windows 7'de tek bir dosya uygulaması çalıştırmak için .NET Runtime 6.0.3 veya sonraki bir sürümü kullanmanız gerekir.

Örnek proje dosyası

Aşağıda tek dosya yayımlamayı belirten örnek bir proje dosyası verilmiştir:

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

Bu özellikler aşağıdaki işlevlere sahiptir:

  • PublishSingleFile. Tek dosya yayımlamayı etkinleştirir. Ayrıca sırasında dotnet buildtek dosya uyarılarını etkinleştirir.
  • SelfContained. Uygulamanın kendi içinde mi yoksa çerçeveye mi bağımlı olduğunu belirler.
  • RuntimeIdentifier. Hedeflediğiniz işletim sistemini ve CPU türünü belirtir. Ayrıca varsayılan olarak ayarlar <SelfContained>true</SelfContained> .

Tek dosyalı uygulamalar her zaman işletim sistemine ve mimariye özeldir. Linux x64, Linux Arm64, Windows x64 gibi her yapılandırma için yayımlamanız gerekir.

*.runtimeconfig.json ve *.deps.json gibi çalışma zamanı yapılandırma dosyaları tek dosyaya eklenir. Ek bir yapılandırma dosyası gerekiyorsa, bunu tek dosyanın yanına yerleştirebilirsiniz.

Tek dosyalı uygulama yayımlama

dotnet publish komutunu kullanarak tek bir dosya uygulaması yayımlayın .

  1. Proje dosyanıza ekleyin <PublishSingleFile>true</PublishSingleFile> .

    Bu değişiklik, bağımsız yayımlamada tek bir dosya uygulaması oluşturur. Ayrıca derleme sırasında tek dosya uyumluluk uyarılarını da gösterir.

    <PropertyGroup>
        <PublishSingleFile>true</PublishSingleFile>
    </PropertyGroup>
    
  2. Kullanarak belirli bir çalışma zamanı tanımlayıcısı için uygulamayı yayımlama dotnet publish -r <RID>

    Aşağıdaki örnek, Windows için uygulamayı bağımsız bir tek dosya uygulaması olarak yayımlar.

    dotnet publish -r win-x64

    Aşağıdaki örnek, Linux için uygulamayı çerçeveye bağımlı tek dosya uygulaması olarak yayımlar.

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

<PublishSingleFile> derleme sırasında dosya analizini etkinleştirmek için proje dosyasında ayarlanmalıdır, ancak bu seçenekleri bağımsız değişken olarak dotnet publish geçirmek de mümkündür:

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

Daha fazla bilgi için bkz . .NET CLI ile .NET Core uygulamaları yayımlama.

Dosyaların eklenmemesini dışla

Aşağıdaki meta veriler ayarlanarak belirli dosyalar tek bir dosyaya eklenmeden açıkça dışlanabilir:

<ExcludeFromSingleFile>true</ExcludeFromSingleFile>

Örneğin, bazı dosyaları yayımlama dizinine yerleştirmek ancak dosyada paketlememek için:

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

Pakete PDB dosyalarını ekleme

Bir derlemenin PDB dosyası, aşağıdaki ayar kullanılarak derlemenin kendisine () .dlleklenebilir. Simgeler derlemenin parçası olduğundan uygulamanın da bir parçasıdır:

<DebugType>embedded</DebugType>

Örneğin, PDB dosyasını bu derlemeye eklemek için bir derlemenin proje dosyasına aşağıdaki özelliği ekleyin:

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

Dikkat edilecek diğer noktalar

Tek dosyalı uygulamalar, uygulamayla birlikte tüm ilgili PDB dosyalarına sahiptir, varsayılan olarak paketlenmez. Oluşturduğunuz projeler için PDB'leri derlemeye eklemek istiyorsanız, olarak ayarlayın DebugTypeembedded. Bkz . Pakete PDB dosyalarını ekleme.

Yönetilen C++ bileşenleri tek dosya dağıtımı için uygun değildir. Tek dosya uyumlu olması için uygulamaları C# dilinde veya yönetilmeyen başka bir C++ dilinde yazmanızı öneririz.

Yerel kitaplıklar

Yalnızca yönetilen DLL'ler uygulamayla birlikte tek bir yürütülebilir dosyada paketlenir. Uygulama başlatıldığında, yönetilen DLL'ler ayıklanır ve belleğe yüklenir ve bir klasöre ayıklanması önlenir. Bu yaklaşımla, yönetilen ikili dosyalar tek dosya paketine eklenir, ancak çekirdek çalışma zamanının kendi yerel ikili dosyaları ayrı dosyalardır.

Ayıklama için bu dosyaları eklemek ve bir çıkış dosyası almak için özelliğini IncludeNativeLibrariesForSelfExtract olarak trueayarlayın.

belirtilmesi IncludeAllContentForSelfExtract , yürütülebilir dosyayı çalıştırmadan önce yönetilen derlemeler de dahil olmak üzere tüm dosyaları ayıklar. Bu, nadir uygulama uyumluluğu sorunları için yararlı olabilir.

Önemli

Ayıklama kullanılırsa, dosyalar uygulama başlamadan önce diske ayıklanır:

  • DOTNET_BUNDLE_EXTRACT_BASE_DIR Ortam değişkeni bir yola ayarlanırsa, dosyalar bu yolun altındaki bir dizine ayıklanır.
  • Aksi takdirde, Linux veya macOS üzerinde çalışıyorsa, dosyalar altında $HOME/.netbir dizine ayıklanır.
  • Windows üzerinde çalışıyorsa, dosyalar altında %TEMP%/.netbir dizine ayıklanır.

Kurcalama önlemek için, bu dizinler farklı ayrıcalıklara sahip kullanıcılar veya hizmetler tarafından yazılamaz. Linux ve macOS sistemlerinin çoğunda /tmp veya /var/tmp kullanmayın.

Not

altında systemdgibi bazı Linux ortamlarında, tanımlanmadığından varsayılan ayıklama çalışmaz $HOME . Böyle durumlarda, açıkça ayarlamanız $DOTNET_BUNDLE_EXTRACT_BASE_DIR önerilir.

için systemdiyi bir alternatif, hizmetinizin birim dosyasında olarak tanımlamaktırDOTNET_BUNDLE_EXTRACT_BASE_DIR. Busystemd, hizmeti çalıştıran hesap için doğru şekilde %h/.net$HOME/.net genişletilir.

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

API uyumsuzluğu

Bazı API'ler tek dosya dağıtımıyla uyumlu değildir. Bu API'leri kullanan uygulamalar değişiklik gerektirebilir. Üçüncü taraf bir çerçeve veya paket kullanıyorsanız, bu API'lerden birini kullanmaları ve değiştirilmesi gerekebilir. Sorunların en yaygın nedeni, uygulamayla birlikte gönderilen dosyalar veya DLL'ler için dosya yollarına bağımlılıktır.

Aşağıdaki tabloda, tek dosya kullanımı için ilgili çalışma zamanı kitaplığı API'sinin ayrıntıları verilmiştir.

API Not
Assembly.CodeBase PlatformNotSupportedExceptionatar.
Assembly.EscapedCodeBase PlatformNotSupportedExceptionatar.
Assembly.GetFile IOExceptionatar.
Assembly.GetFiles IOExceptionatar.
Assembly.Location Boş bir dize döndürür.
AssemblyName.CodeBase null döndürür.
AssemblyName.EscapedCodeBase null döndürür.
Module.FullyQualifiedName değerine <Unknown> sahip bir dize döndürür veya özel durum oluşturur.
Marshal.GetHINSTANCE -1 döndürür.
Module.Name değeriyle <Unknown>bir dize döndürür.

Yaygın senaryoları düzeltmek için bazı önerilerimiz vardır:

  • Yürütülebilir dosyanın yanındaki dosyalara erişmek için kullanın AppContext.BaseDirectory.

  • Yürütülebilir dosyanın adını bulmak için dosyasının ilk öğesini Environment.GetCommandLineArgs()kullanın veya .NET 6'dan ProcessPathbaşlayarak dosyasındaki dosya adını kullanın.

  • Gevşek dosyaların tamamen gönderimini önlemek için ekli kaynakları kullanmayı göz önünde bulundurun.

Paketlemeden önce ikili dosyaları işleme sonrası

Bazı iş akışları paketlemeden önce ikili dosyaların işlenmesini gerektirir. İmzalama yaygın bir örnektir. dotnet SDK'sı, tek dosya paketlemeden hemen önce ikili dosyaların işlenmesine izin vermek için MSBuild uzantı noktaları sağlar. Kullanılabilir API'ler şunlardır:

  • Daha önce çağrılacak bir hedef PrepareForBundleGenerateSingleFileBundle
  • <ItemGroup><FilesToBundle /></ItemGroup> Paketlenecek tüm dosyaları içeren
  • apphost şablonunu belirtecek özellik AppHostFile . İşlem sonrası, apphost'un işlenmesini dışlamak isteyebilir.

Buna bağlanmak için ve GenerateSingleFileBundlearasında PrepareForBundle yürütülecek bir hedef oluşturulması gerekir.

Aşağıdaki .NET proje Target düğümü örneğini göz önünde bulundurun:

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

İmzalama işlemi sırasında araçların dosyaları kopyalaması gerekebilir. Bu durum, özgün dosya derlemeye ait olmayan paylaşılan bir öğeyse (örneğin, dosya bir NuGet önbelleğinden geliyorsa) oluşabilir. Böyle bir durumda, aracın değiştirilen kopyayı işaret edecek şekilde ilgili FilesToBundle öğenin yolunu değiştirmesi beklenir.

Tek dosyalı uygulamalarda derlemeleri sıkıştırma

Tek dosyalı uygulamalar, eklenmiş derlemelerde sıkıştırma etkin olarak oluşturulabilir. EnableCompressionInSingleFile özelliğini true olarak ayarlayın. Oluşturulan tek dosyada tüm eklenmiş derlemeler sıkıştırılır ve bu da yürütülebilir dosyanın boyutunu önemli ölçüde azaltabilir.

Sıkıştırmanın bir performans maliyeti vardır. Uygulama başlangıcında derlemelerin belleğe sıkıştırılması gerekir ve bu işlem biraz zaman alır. Kullanmadan önce sıkıştırmayı etkinleştirmenin boyut değişikliğini ve başlangıç maliyetini ölçmenizi öneririz. Etki, farklı uygulamalar arasında önemli ölçüde farklılık gösterebilir.

Tek dosyalı bir uygulamayı inceleme

Tek dosya uygulamaları ILSpy aracı kullanılarak incelenebilir. Araç, uygulamaya paketlenmiş tüm dosyaları gösterebilir ve yönetilen derlemelerin içeriğini inceleyebilir.

Ayrıca bkz.