Aracılığıyla paylaş


Visual Studio derleme işlemini genişletme

Visual Studio derleme işlemi, proje dosyanıza aktarılan bir dizi MSBuild .targets dosyası tarafından tanımlanır. Visual Studio projelerinin genellikle kullandığı bir SDK kullanıyorsanız, bu içeri aktarma işlemleri örtük olarak kullanılmaktadır. İçeri aktarılan bu dosyalardan biri olan Microsoft.Common.targets, derleme işleminin çeşitli noktalarında özel görevleri çalıştırmanıza olanak sağlayacak şekilde genişletilebilir. Bu makalede, Visual Studio derleme işlemini genişletmek için kullanabileceğiniz üç yöntem açıklanmaktadır:

  • Özel bir hedef oluşturun ve ve AfterTargets özniteliklerini kullanarak BeforeTargets ne zaman çalıştırılacağını belirtin.

  • DependsOn Ortak hedeflerde tanımlanan özellikleri geçersiz kılın.

  • Ortak hedeflerde tanımlanan belirli önceden tanımlanmış hedefleri geçersiz kılın (Microsoft.Common.targets veya içeri aktardığı dosyalar).

AfterTargets ve BeforeTargets

Özel hedefinizde ve BeforeTargets özniteliklerini kullanarak AfterTargets ne zaman çalıştırılacağını belirtebilirsiniz.

Aşağıdaki örnekte, çıkış dosyalarıyla AfterTargets bir şey yapmayan özel bir hedef eklemek için özniteliğinin nasıl kullanılacağı gösterilmektedir. Bu durumda, çıkış dosyalarını yeni bir CustomOutput klasörüne kopyalar. Örnek ayrıca bir öznitelik kullanarak ve özel temizleme işleminin hedef öncesinde CoreClean çalıştırılacağını belirterek özel derleme işlemi tarafından oluşturulan dosyaların hedefle CustomCleanBeforeTargets nasıl temizleneceğini gösterir.

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
     <TargetFramework>netcoreapp3.1</TargetFramework>
     <_OutputCopyLocation>$(OutputPath)..\..\CustomOutput\</_OutputCopyLocation>
  </PropertyGroup>

  <Target Name="CustomAfterBuild" AfterTargets="Build">
    <ItemGroup>
      <_FilesToCopy Include="$(OutputPath)**\*"/>
    </ItemGroup>
    <Message Text="_FilesToCopy: @(_FilesToCopy)" Importance="high"/>

    <Message Text="DestFiles:
        @(_FilesToCopy->'$(_OutputCopyLocation)%(RecursiveDir)%(Filename)%(Extension)')"/>

    <Copy SourceFiles="@(_FilesToCopy)"
          DestinationFiles=
          "@(_FilesToCopy->'$(_OutputCopyLocation)%(RecursiveDir)%(Filename)%(Extension)')"/>
  </Target>

  <Target Name="CustomClean" BeforeTargets="CoreClean">
    <Message Text="Inside Custom Clean" Importance="high"/>
    <ItemGroup>
      <_CustomFilesToDelete Include="$(_OutputCopyLocation)**\*"/>
    </ItemGroup>
    <Delete Files='@(_CustomFilesToDelete)'/>
  </Target>
</Project>

Uyarı

Önceden tanımlanmış hedefler, bunları da tanımlayan SDK içeri aktarması tarafından geçersiz kılındığından, önceden tanımlanmış hedeflerden farklı adlar kullandığınızdan emin olun (örneğin, buradaki CustomAfterBuildözel derleme hedefi , değil AfterBuild). Önceden tanımlanmış hedeflerin listesi için bu makalenin sonundaki tabloya bakın.

DependsOn özelliklerini genişletme

Derleme işlemini genişletmenin bir diğer yolu, standart hedeflerden önce çalıştırılması gereken hedefleri belirtmek için özellikleri (örneğin, BuildDependsOn) kullanmaktırDependsOn.

Bu yöntem, sonraki bölümde ele alınan önceden tanımlanmış hedefleri geçersiz kılmaya tercih edilir. Önceden tanımlanmış hedefleri geçersiz kılma hala desteklenen eski bir yöntemdir, ancak MSBuild hedeflerin tanımını sırayla değerlendirdiğinden, projenizi içeri aktaran başka bir projenin zaten geçersiz kıldığınız hedefleri geçersiz kılmasını önlemenin bir yolu yoktur. Bu nedenle, örneğin, diğer tüm projeler içeri aktarıldıktan sonra proje dosyasında tanımlanan son AfterBuild hedef, derleme sırasında kullanılan hedef olacaktır.

Ortak hedefler genelinde özniteliklerde DependsOnTargets kullanılan özellikleri geçersiz kılarak DependsOn hedeflerin istenmeyen geçersiz kılmalarına karşı koruma sağlayabilirsiniz. Örneğin, Build hedef özniteliği DependsOnTargets değerini "$(BuildDependsOn)"içerir. Aşağıdakileri dikkate alın:

<Target Name="Build" DependsOnTargets="$(BuildDependsOn)"/>

Bu XML parçası, hedefin Build çalıştırılabilmesi için önce özelliğinde belirtilen tüm hedeflerin BuildDependsOn çalıştırılması gerektiğini belirtir. BuildDependsOn özelliği şu şekilde tanımlanır:

<PropertyGroup>
    <BuildDependsOn>
        $(BuildDependsOn);
        BeforeBuild;
        CoreBuild;
        AfterBuild
    </BuildDependsOn>
</PropertyGroup>

Proje dosyanızın sonunda adlı BuildDependsOn başka bir özellik bildirerek bu özellik değerini geçersiz kılabilirsiniz. SDK stilindeki bir projede bu, açık içeri aktarmaları kullanmanız gereken anlamına gelir. Özelliği son içeri aktarma işleminden sonra koyabilmeniz için bkz. Örtük ve açık içeri aktarmalar.DependsOn Önceki BuildDependsOn özelliği yeni özelliğe ekleyerek, hedef listenin başına ve sonuna yeni hedefler ekleyebilirsiniz. Örneğin:

<PropertyGroup>
    <BuildDependsOn>
        MyCustomTarget1;
        $(BuildDependsOn);
        MyCustomTarget2
    </BuildDependsOn>
</PropertyGroup>

<Target Name="MyCustomTarget1">
    <Message Text="Running MyCustomTarget1..."/>
</Target>
<Target Name="MyCustomTarget2">
    <Message Text="Running MyCustomTarget2..."/>
</Target>

Proje dosyanızı içeri aktaran projeler, yaptığınız özelleştirmelerin üzerine yazmadan bu özellikleri daha da genişletebilir.

DependsOn özelliğini geçersiz kılmak için

  1. Geçersiz kılmak istediğiniz ortak hedeflerde önceden tanımlanmış DependsOn bir özelliği tanımlayın. Yaygın olarak geçersiz kılınan DependsOn özelliklerin listesi için aşağıdaki tabloya bakın.

  2. Proje dosyanızın sonunda özelliğin veya özelliklerin başka bir örneğini tanımlayın. Özgün özelliğini ( örneğin $(BuildDependsOn), ) yeni özelliğe ekleyin.

  3. Özellik tanımından önce veya sonra özel hedeflerinizi tanımlayın.

  4. Proje dosyasını oluşturun.

Genellikle geçersiz kılınan DependsOn özellikleri

Özellik adı Bu noktadan önce çalıştırılacak hedefler eklendi:
BuildDependsOn Ana derleme giriş noktası. Derleme işleminin tamamına özel hedefler eklemek istiyorsanız bu özelliği geçersiz kılın.
RebuildDependsOn Rebuild
RunDependsOn Son derleme çıkışının yürütülmesi (.EXE ise)
CompileDependsOn Derleme (Compile hedef). Derleme adımından önce veya sonra özel işlemler eklemek istiyorsanız bu özelliği geçersiz kılın.
CreateSatelliteAssembliesDependsOn Uydu derlemelerinin oluşturulması
CleanDependsOn Hedef Clean (Tüm ara ve son derleme çıkışlarının silinmesi). Özel derleme işleminizin çıkışını temizlemek istiyorsanız bu özelliği geçersiz kılın.
PostBuildEventDependsOn Hedef PostBuildEvent
PublishBuildDependsOn Derleme yayımlama
ResolveAssemblyReferencesDependsOn Hedef ResolveAssemblyReferences (belirli bir bağımlılık için bağımlılıkların geçişli kapanışını bulma). Bkz. ResolveAssemblyReference.

Örnek: BuildDependsOn ve CleanDependsOn

Aşağıdaki örnek ve AfterTargets örneğine BeforeTargets benzer, ancak benzer işlevlerin nasıl elde edilemeye devam ettiği gösterilmektedir. Derlemeden sonra çıkış dosyalarını kopyalayan kendi görevinizi CustomAfterBuild eklemek için kullanarak BuildDependsOn derlemeyi genişletir ve ayrıca kullanarak CleanDependsOnilgili CustomClean görevi ekler.

Bu örnekte bu, SDK stilinde bir projedir. Bu makalenin önceki bölümlerinde SDK stilindeki projeler hakkında notta belirtildiği gibi, Visual Studio'nun proje dosyaları oluştururken kullandığı öznitelik yerine Sdk el ile içeri aktarma yöntemini kullanmanız gerekir.

<Project>
  <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk"/>

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk"/>

  <PropertyGroup>
    <BuildDependsOn>
      $(BuildDependsOn);CustomAfterBuild
    </BuildDependsOn>

    <CleanDependsOn>
      $(CleanDependsOn);CustomClean
    </CleanDependsOn>

    <_OutputCopyLocation>$(OutputPath)..\..\CustomOutput\</_OutputCopyLocation>
  </PropertyGroup>

  <Target Name="CustomAfterBuild">
    <ItemGroup>
      <_FilesToCopy Include="$(OutputPath)**\*"/>
    </ItemGroup>
    <Message Importance="high" Text="_FilesToCopy: @(_FilesToCopy)"/>

    <Message Text="DestFiles:
      @(_FilesToCopy-&gt;'$(_OutputCopyLocation)%(RecursiveDir)%(Filename)%(Extension)')"/>

    <Copy SourceFiles="@(_FilesToCopy)"
          DestinationFiles="@(_FilesToCopy-&gt;'$(_OutputCopyLocation)%(RecursiveDir)%(Filename)%(Extension)')"/>
  </Target>

  <Target Name="CustomClean">
    <Message Importance="high" Text="Inside Custom Clean"/>
    <ItemGroup>
      <_CustomFilesToDelete Include="$(_OutputCopyLocation)**\*"/>
    </ItemGroup>
    <Delete Files="@(_CustomFilesToDelete)"/>
  </Target>
</Project>

Öğelerin sırası önemlidir. BuildDependsOn ve CleanDependsOn öğeleri, standart SDK hedefleri dosyası içeri aktarıldıktan sonra görünmelidir.

Önceden tanımlanmış hedefleri geçersiz kılma

Ortak .targets dosyalar, derleme işlemindeki bazı ana hedeflerden önce ve sonra çağrılan önceden tanımlanmış boş hedefler kümesi içerir. Örneğin, MSBuild ana hedef önce CoreBuild hedef çağırır BeforeBuild ve AfterBuild hedef sonra CoreBuild hedef. Varsayılan olarak, ortak hedeflerdeki boş hedefler hiçbir şey yapmaz, ancak bir proje dosyasında istediğiniz hedefleri tanımlayarak varsayılan davranışlarını geçersiz kılabilirsiniz. Bu makalenin önceki bölümlerinde açıklanan yöntemler tercih edilir, ancak bu yöntemi kullanan eski kodlarla karşılaşabilirsiniz.

Projeniz bir SDK kullanıyorsa (örneğin Microsoft.Net.Sdk), açık ve örtük içeri aktarmalarda açıklandığı gibi örtük olandan açık içeri aktarmalara bir değişiklik yapmanız gerekir.

Önceden tanımlanmış bir hedefi geçersiz kılmak için

  1. Proje özniteliğini Sdk kullanıyorsa, bunu açık içeri aktarma söz dizimi olarak değiştirin. Bkz. Açık ve örtük içeri aktarmalar.

  2. Geçersiz kılmak istediğiniz ortak hedeflerde önceden tanımlanmış bir hedefi tanımlayın. Güvenli bir şekilde geçersiz kılabileceğiniz hedeflerin tam listesi için aşağıdaki tabloya bakın.

  3. Hedef veya hedefleri proje dosyanızın sonunda, etiketin </Project> hemen öncesinde ve açık SDK içeri aktarma işleminden sonra tanımlayın. Örneğin:

    <Project>
        <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
        ...
        <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
        <Target Name="BeforeBuild">
            <!-- Insert tasks to run before build here -->
        </Target>
        <Target Name="AfterBuild">
            <!-- Insert tasks to run after build here -->
        </Target>
    </Project>
    

    Sdk Üst düzey Project öğedeki özniteliğin kaldırıldığını unutmayın.

  4. Proje dosyasını oluşturun.

Önceden tanımlanmış hedeflerin tablosu

Aşağıdaki tabloda, geçersiz kılabileceğiniz ortak hedeflerdeki tüm hedefler gösterilmektedir.

Hedef adı Açıklama
BeforeCompile, AfterCompile Bu hedeflerden birine eklenen görevler çekirdek derlemesi yapılmadan önce veya sonra çalıştırılır. Özelleştirmelerin çoğu bu iki hedef arasında gerçekleştirilir.
BeforeBuild, AfterBuild Bu hedeflerden birine eklenen görevler, derlemedeki diğer her şeyden önce veya sonra çalıştırılır. Not:BeforeBuild ve AfterBuild hedefleri çoğu proje dosyasının sonundaki açıklamalarda zaten tanımlanmıştır ve böylece proje dosyanıza derleme öncesi ve sonrası olayları kolayca ekleyebilirsiniz.
BeforeRebuild, AfterRebuild Bu hedeflerden birine eklenen görevler, çekirdek yeniden oluşturma işlevi çağrılmadan önce veya sonra çalıştırılır. Microsoft.Common.targets'ta hedef yürütme sırası: BeforeRebuild, Clean, Buildve sonra AfterRebuild.
BeforeClean, AfterClean Bu hedeflerden birine eklenen görevler, çekirdek temizleme işlevi çağrılmadan önce veya sonra çalıştırılır.
BeforePublish, AfterPublish Bu hedeflerden birine eklenen görevler, çekirdek yayımlama işlevi çağrılmadan önce veya sonra çalıştırılır.
BeforeResolveReferences, AfterResolveReferences Bu hedeflerden birine eklenen görevler, derleme başvuruları çözümlenmeden önce veya sonra çalıştırılır.
BeforeResGen, AfterResGen Bu hedeflerden birine eklenen görevler, kaynaklar oluşturulmadan önce veya sonra çalıştırılır.

Derleme sisteminde ve .NET SDK'sında daha birçok hedef vardır. Bkz . MSBuild hedefleri - SDK ve varsayılan derleme hedefleri.

Özel hedefler için en iyi yöntemler

özellikleri DependsOnTargets ve BeforeTargets her ikisi de bir hedefin başka bir hedef öncesinde çalıştırılması gerektiğini belirtebilir, ancak her ikisi de farklı senaryolarda gereklidir. Bağımlılık gereksiniminin belirtildiği hedefte farklılık gösterir. Yalnızca kendi hedefleriniz üzerinde denetim sahibi olursunuz ve sistem hedeflerini veya içeri aktarılan diğer hedefleri güvenli bir şekilde değiştiremezsiniz; böylece yöntem seçiminiz kısıtlanır.

Özel bir hedef yazarken, hedefinizin hedeflenen sırada yürütülmesini sağlamak için bu genel yönergeleri izleyin.

  1. DependsOnTargets Hedefiniz yürütülmeden önce yapılması gereken hedefleri belirtmek için özniteliğini kullanın. Denetlediğiniz bir hedef zinciri için her hedef içindeki zincirin DependsOnTargetsönceki üyesini belirtebilir.

  2. Daha önce yürütmeniz gerekenleri denetlemediğiniz herhangi bir hedef için kullanın BeforeTargets (derlemenin erken bir bölümünde çalışması gereken bir hedef için olduğu gibi BeforeTargets="PrepareForBuild" ).

  3. İhtiyacınız olan çıkışların kullanılabilir olduğunu garanti eden, denetlemediğiniz herhangi bir hedef için kullanın AfterTargets . Örneğin, başvuru listesini değiştirecek bir şey için belirtin AfterTargets="ResolveReferences" .

  4. Bunları birlikte kullanabilirsiniz. Örneğin, DependsOnTargets="GenerateAssemblyInfo" BeforeTargets="BeforeCompile".

Açık ve örtük içeri aktarmalar

Visual Studio tarafından oluşturulan projeler genellikle proje öğesinde özniteliğini kullanır Sdk . Bu tür projeler SDK stili projeler olarak adlandırılır. Bkz . MSBuild proje SDK'larını kullanma. Bir örnek aşağıda verilmiştir:

<Project Sdk="Microsoft.Net.Sdk">

Projeniz özniteliğini kullandığında Sdk , biri proje dosyanızın başına, diğeri de sonuna iki içeri aktarma örtük olarak eklenir.

Örtük içeri aktarmalar, öğesinden sonra proje dosyasındaki ilk satır olarak aşağıdaki gibi bir içeri aktarma deyimine Project sahip olmakla eşdeğerdir:

<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />

ve proje dosyasındaki son satır olarak aşağıdaki içeri aktarma deyimi:

<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />

Bu söz dizimi, açık SDK içeri aktarmaları olarak adlandırılır. Bu açık söz dizimini kullandığınızda, proje öğesinde özniteliğini Sdk atlamalısınız.

Örtük SDK içeri aktarma işlemi, belirli "ortak" .props veya .targets eski proje dosyalarındaki tipik bir yapı olan dosyaları içeri aktarmaya eşdeğerdir, örneğin:

<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />

ile

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

Bu tür eski başvurular, bu bölümün başlarında gösterilen açık SDK söz dizimi ile değiştirilmelidir.

Açık SDK söz dizimini kullanmak, ilk içeri aktarma işleminden önce veya son SDK içeri aktarma işleminden sonra kendi kodunuzu ekleyebileceğiniz anlamına gelir. Bu, içeri aktarılan .props dosyada etkili olacak ilk içeri aktarma işleminden önce özellikleri ayarlayarak davranışı değiştirebileceğiniz ve son içeri aktarma işleminden sonra SDK .targets dosyalarından birinde tanımlanan bir hedefi geçersiz kılabileceğiniz anlamına gelir. Bu yöntemi kullanarak veya daha sonra açıklandığı gibi geçersiz kılabilirsiniz BeforeBuildAfterBuild .

Sonraki adımlar

Derlemeyi özelleştirmek için MSBuild ile yapabileceğiniz çok daha fazla şey vardır. Bkz. Derlemenizi özelleştirme.