Dela via


Självstudie: Använda MSBuild

MSBuild är byggplattformen för Microsoft och Visual Studio. Den här självstudien beskriver byggstenarna i MSBuild och visar hur du skriver, manipulerar och felsöker MSBuild-projekt. Du lär dig mer om:

  • Skapa och manipulera en projektfil.

  • Så här använder du byggegenskaper.

  • Så här använder du byggobjekt.

Du kan köra MSBuild från Visual Studio eller från kommandofönstret . I den här självstudien skapar du en MSBuild-projektfil med hjälp av Visual Studio. Du redigerar projektfilen i Visual Studio och använder kommandofönstret för att skapa projektet och granska resultaten.

Installera MSBuild

Om du har Visual Studio har du redan MSBuild installerat. Med Visual Studio 2019 och senare installeras det under installationsmappen för Visual Studio. För en typisk standardinstallation på Windows 10 finns MSBuild.exe under installationsmappen i MSBuild\Current\Bin.

I installationsprogrammet kontrollerar du att MSBuild-verktygen för de arbetsbelastningar som du använder är markerade och väljer Installera.

Installera MSBuild

Om du vill installera MSBuild på ett system som inte har Visual Studio går du till Build Tools för Visual Studio 2019eller installerar .NET SDK.

Om du har Visual Studio har du redan MSBuild installerat. Med Visual Studio 2022 installeras det under installationsmappen för Visual Studio. För en typisk standardinstallation på Windows 10 finns MSBuild.exe under installationsmappen i MSBuild\Current\Bin.

I Installationsprogrammet för Visual Studio navigerar du till Enskilda komponenteroch letar upp kryssrutan för MSBuild. Den väljs automatiskt när du väljer någon av de andra arbetsbelastningarna som ska installeras.

Om du vill installera MSBuild på ett system som inte har Visual Studio går du till Build Tools for Visual Studio 2022 på sidan nedladdningar. Ett annat sätt att hämta MSBuild är att installera .NET SDK.

Skapa ett MSBuild-projekt

Visual Studio-projektsystemet baseras på MSBuild. Det är enkelt att skapa en ny projektfil med Visual Studio. I det här avsnittet skapar du en C#-projektfil. Du kan välja att skapa en Visual Basic-projektfil i stället. I den här handledningen är skillnaden mellan de två projektfilerna mindre.

Skapa en projektfil

  1. Öppna Visual Studio och skapa ett projekt:

    I sökrutan skriver du winformsoch väljer sedan Skapa en ny Windows Forms App (.NET Framework). I dialogrutan som visas väljer du Skapa.

    I rutan Projektnamn skriver du BuildApp. Ange en plats för lösningen, till exempel D:\.

  2. Klicka på OK eller Skapa för att skapa projektfilen.

Granska projektfilen

I föregående avsnitt använde du Visual Studio för att skapa en C#-projektfil. Projektfilen representeras i Solution Explorer av projektnoden med namnet BuildApp. Du kan använda Visual Studio-kodredigeraren för att undersöka projektfilen.

Att undersöka projektfilen

  1. I Solution Explorerklickar du på projektnoden BuildApp.

  2. Observera att egenskapen Project File är BuildApp.csproji webbläsaren Properties . Alla projektfiler namnges med suffixet proj. Om du hade skapat ett Visual Basic-projekt skulle projektfilens namn vara BuildApp.vbproj.

  3. Högerklicka på projektnoden igen och klicka sedan på Redigera BuildApp.csproj.

    Projektfilen visas i kodredigeraren.

Not

För vissa projekttyper, till exempel C++, måste du ta bort projektet (högerklicka på projektfilen och välja Ta bort projekt) innan du kan öppna och redigera projektfilen.

Mål och uppgifter

Projektfiler är XML-formaterade filer med rotnoden Project.

De flesta .NET-projekt har ett Sdk attribut. Dessa projekt kallas för SDK-liknande projekt. Att referera till ett SDK innebär att MSBuild importerar en uppsättning filer som tillhandahåller bygginfrastrukturen för SDK:t. Om du inte refererar till något SDK kan du fortfarande använda MSBuild. Du kommer bara inte automatiskt att ha alla SDK-specifika egenskaper och mål tillgängliga för dig.

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

Det finns många varianter av .NET SDK:er för särskilda ändamål. de beskrivs på .NET Project SDK:er.

Arbetet med att skapa ett program utförs med elementen Target och Task.

  • En uppgift är den minsta arbetsenheten, med andra ord "atomen" i en kompilering. Uppgifter är oberoende körbara komponenter som kan ha indata och utdata. Det finns för närvarande inga uppgifter som refereras till eller definieras i projektfilen. Du lägger till aktiviteter i projektfilen i följande avsnitt. Mer information finns i Uppgifter.

  • Ett mål är en namngiven sekvens med uppgifter. Det kan vara en namngiven sekvens med uppgifter, men kritiskt nog representerar det något som ska skapas eller göras, så det bör definieras på ett målorienterat sätt. Mer information finns i Targets.

Standardmålet definieras inte i projektfilen. I stället anges den i importerade projekt. Elementet Import anger importerade projekt. I ett C#-projekt importeras till exempel standardmålet från filen Microsoft.CSharp.targets.

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

Importerade filer infogas effektivt i projektfilen var de än refereras.

I SDK-projekt ser du inte det här importelementet eftersom SDK-attributet gör att filen importeras implicit.

MSBuild håller reda på målen för en version och garanterar att varje mål inte skapas mer än en gång.

Lägga till ett mål och en uppgift

Lägg till ett mål i projektfilen. Lägg till en uppgift i syftet som skriver ut ett meddelande.

Om du vill lägga till ett mål och en uppgift

  1. Lägg till de här raderna i projektfilen, precis efter importinstruktionen eller det inledande Project-elementet.

    <Target Name="HelloWorld">
    </Target>
    

    Den här koden skapar ett mål med namnet HelloWorld. Observera att du har IntelliSense-stöd när du redigerar projektfilen.

  2. Lägg till rader i HelloWorld-målet så att det resulterande avsnittet ser ut så här:

    <Target Name="HelloWorld">
      <Message Text="Hello"></Message>
      <Message Text="World"></Message>
    </Target>
    
  3. Spara projektfilen.

Den Message uppgiften är en av de många uppgifter som levereras med MSBuild. En fullständig lista över tillgängliga uppgifter och användningsinformation finns i Uppgiftsreferens.

Den Message aktiviteten tar strängvärdet för attributet Text som indata och visar det på utdataenheten (eller skriver det till en eller flera loggar, om tillämpligt). Det HelloWorld målet kör meddelandeaktiviteten två gånger: först för att visa "Hello" och sedan för att visa "World".

Skapa målet

Om du försöker skapa det här projektet från Visual Studio skapas inte det mål som du har definierat. Det beror på att Visual Studio väljer standardmålet, som fortfarande är det i den importerade .targets-filen.

Kör MSBuild från kommandotolken Developer för Visual Studio för att skapa det HelloWorld-mål som definierades tidigare. Använd kommandoradsväxeln -target eller -t för att välja målet.

Not

Vi kommer att referera till Developer Command Prompt som kommandofönster i kommande avsnitt.

Så här skapar du målet:

  1. Öppna kommandofönstret .

    I sökrutan i aktivitetsfältet börjar du skriva namnet på verktyget, till exempel dev eller developer command prompt. En lista över installerade appar som matchar ditt sökmönster visas.

    Om du behöver hitta den manuellt finner du filen LaunchDevCmd.bat i mappen {Visual Studio-installationsmapp}\Common7\Tools.

  2. I kommandofönstret navigerar du till mappen som innehåller projektfilen, i det här fallet D:\BuildApp\BuildApp.

  3. Kör msbuild med kommandoväxeln -t:HelloWorld. Det här kommandot väljer och skapar HelloWorld-målet:

    msbuild buildapp.csproj -t:HelloWorld
    
  4. Granska utdata i -kommandofönstret. Du bör se de två raderna "Hello" och "World":

    Hello
    World
    

Not

Om du i stället ser The target "HelloWorld" does not exist in the project har du förmodligen glömt att spara projektfilen i kodredigeraren. Spara filen och försök igen.

Genom att växla mellan kodredigeraren och kommandofönstret kan du ändra projektfilen och snabbt se resultatet.

Skapa egenskaper

Byggegenskaper är namn/värde-par som vägleder bygget. Flera byggegenskaper har redan definierats överst i projektfilen:

<PropertyGroup>
...
  <ProductVersion>10.0.11107</ProductVersion>
  <SchemaVersion>2.0</SchemaVersion>
  <ProjectGuid>{30E3C9D5-FD86-4691-A331-80EA5BA7E571}</ProjectGuid>
  <OutputType>WinExe</OutputType>
...
</PropertyGroup>

Samtliga egenskaper är underordnade element i PropertyGroup-element. Namnet på egenskapen är namnet på det underordnade elementet och värdet för egenskapen är textelementet i det underordnade elementet. Till exempel

<TargetFrameworkVersion>net8.0</TargetFrameworkVersion>

definierar egenskapen med namnet TargetFrameworkVersion, vilket ger strängvärdet "net8.0"

Byggegenskaper kan när som helst omdefinieras. Om

<TargetFrameworkVersion>net6.0</TargetFrameworkVersion>

Om det visas senare i projektfilen, eller i en fil som importerats senare i projektfilen, då tar TargetFrameworkVersion det nya värdet "net6.0"

Granska ett egenskapsvärde

Om du vill hämta värdet för en egenskap använder du följande syntax, där PropertyName är namnet på egenskapen:

$(PropertyName)

Använd den här syntaxen för att undersöka några av egenskaperna i projektfilen.

Att undersöka ett egenskapsvärde

  1. Ersätt HelloWorld-målet med den här koden från kodredigeraren:

    <Target Name="HelloWorld">
      <Message Text="Configuration is $(Configuration)" />
      <Message Text="MSBuildToolsPath is $(MSBuildToolsPath)" />
    </Target>
    
  2. Spara projektfilen.

  3. Från -kommandofönstretanger du och kör den här raden:

    msbuild buildapp.csproj -t:HelloWorld
    
  4. Granska utdata. Du bör se dessa två rader (dina utdata kan skilja sig åt):

    Configuration is Debug
    MSBuildToolsPath is C:\Program Files\Microsoft Visual Studio\2022\MSBuild\Current\Bin\amd64
    
    Configuration is Debug
    MSBuildToolsPath is C:\Program Files (x86)\Microsoft Visual Studio\2019\MSBuild\16.0\Bin
    

Villkorsstyrda egenskaper

Många egenskaper som Configuration definieras villkorsstyrt, d.v.s. attributet Condition visas i egenskapselementet. Villkorsstyrda egenskaper definieras eller omdefinieras endast om villkoret utvärderas till "sant". Odefinierade egenskaper får standardvärdet för en tom sträng. Till exempel

<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>

betyder "Om konfigurationsegenskapen inte har definierats ännu definierar du den och ger den värdet "Felsöka".

Nästan alla MSBuild-element kan ha ett Condition attribut. Mer information om hur du använder attributet Condition finns i Villkor.

Reserverade egenskaper

MSBuild reserverar vissa egenskapsnamn för att lagra information om projektfilen och MSBuild-binärfilerna. MSBuildToolsPath är ett exempel på en reserverad egenskap. Reserverade egenskaper refereras till med $ notation som vilken annan egenskap som helst. Mer information finns i Så refererar du till namnet eller platsen för projektfilen och MSBuild-reserverade och kända egenskaper.

Miljövariabler

Du kan referera till miljövariabler i projektfiler på samma sätt som byggegenskaper. Om du till exempel vill använda miljövariabeln PATH i projektfilen använder du $(Path). Om projektet innehåller en egenskapsdefinition som har samma namn som en miljövariabel åsidosätter egenskapen i projektet värdet för miljövariabeln. Mer information finns i Så här: Använd miljövariabler i en byggnad.

Ange egenskaper från kommandoraden

Egenskaper kan definieras på kommandoraden med hjälp av kommandoradsväxeln -property eller -p. Egenskapsvärden som tas emot från kommandoraden åsidosätter egenskapsvärden som anges i projektfilen och miljövariablerna.

Ange ett egenskapsvärde från kommandoraden:

  1. Från -kommandofönstretanger du och kör den här raden:

    msbuild buildapp.csproj -t:HelloWorld -p:Configuration=Release
    
  2. Granska utdata. Du bör se den här raden:

    Configuration is Release.
    

MSBuild skapar egenskapen Configuration och ger den värdet "Release".

Specialtecken

Vissa tecken har särskild betydelse i MSBuild-projektfiler. Exempel på dessa tecken är semikolon (;) och asterisker (*). För att kunna använda dessa specialtecken som literaler i en projektfil måste de anges med hjälp av syntaxen %<xx>, där <xx> representerar ASCII hexadecimalt värde för tecknet.

Ändra meddelandeaktiviteten så att värdet av konfigurationsegenskapen visas med specialtecken för att göra den mer lättläst.

Om du vill använda specialtecken i meddelandeaktiviteten:

  1. Ersätt båda meddelandeuppgifterna i kodredigeraren med den här raden:

    <Message Text="%24(Configuration) is %22$(Configuration)%22" />
    
  2. Spara projektfilen.

  3. Från -kommandofönstretanger du och kör den här raden:

    msbuild buildapp.csproj -t:HelloWorld
    
  4. Granska utdata. Du bör se den här raden:

    $(Configuration) is "Debug"
    

Mer information finns i specialtecken för MSBuild.

Skapa objekt

Ett objekt är en del av informationen, vanligtvis ett filnamn, som används som indata till byggsystemet. En samling objekt som representerar källfiler kan till exempel skickas till en uppgift med namnet Kompilera för att kompilera dem till en sammansättning.

Alla objekt är underordnade element i ItemGroup-element. Objektnamnet är namnet på det underordnade elementet och objektvärdet är värdet för attributet Include för det underordnade elementet. Värdena för objekt med samma namn samlas in i objekttyper av det namnet. Till exempel

<ItemGroup>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>

definierar en objektgrupp som innehåller två objekt. Objekttypen Kompilera har två värden: Program.cs och Properties\AssemblyInfo.cs.

Följande kod skapar samma objekttyp genom att deklarera båda filerna i ett Include attribut, avgränsade med ett semikolon.

<ItemGroup>
    <Compile Include="Program.cs;Properties\AssemblyInfo.cs" />
</ItemGroup>

Mer information finns i Objekt.

Not

Filsökvägarna är relativa till mappen som innehåller MSBuild-projektfilen, även om projektfilen är en importerad projektfil. Det finns några undantag, till exempel när du använder Import och UsingTask-element.

Granska objekttypsvärden

Om du vill hämta värdena för en objekttyp använder du följande syntax, där ItemType är namnet på objekttypen:

@(ItemType)

Använd den här syntaxen för att undersöka Compile objekttypen i projektfilen.

För att undersöka objekttypsvärden:

  1. Från kodredigeraren ersätter du HelloWorld-måluppgiften med den här koden:

    <Target Name="HelloWorld">
      <Message Text="Compile item type contains @(Compile)" />
    </Target>
    
  2. Spara projektfilen.

  3. Från -kommandofönstretanger du och kör den här raden:

    msbuild buildapp.csproj -t:HelloWorld
    
  4. Granska utdata. Du bör se den här långa raden:

    Compile item type contains Form1.cs;Form1.Designer.cs;Program.cs;Properties\AssemblyInfo.cs;Properties\Resources.Designer.cs;Properties\Settings.Designer.cs
    

Värdena för en objekttyp avgränsas med semikolon som standard.

Om du vill ändra avgränsaren för en objekttyp använder du följande syntax, där ItemType är objekttypen och Avgränsaren är en sträng med ett eller flera avgränsande tecken:

@(ItemType, Separator)

Ändra Message uppgift så att den använder vagnreturer och radflöden (%0A%0D) för att visa Kompilera objekt en per rad.

Om du vill visa objekttypsvärden en per rad

  1. Byt ut Meddelande-uppgiften mot denna rad i kodredigeraren:

    <Message Text="Compile item type contains @(Compile, '%0A%0D')" />
    
  2. Spara projektfilen.

  3. Från -kommandofönstretanger du och kör den här raden:

    msbuild buildapp.csproj -t:HelloWorld
    
  4. Granska utdata. Du bör se följande rader:

    Compile item type contains Form1.cs
    Form1.Designer.cs
    Program.cs
    Properties\AssemblyInfo.cs
    Properties\Resources.Designer.cs
    Properties\Settings.Designer.cs
    

Inkludera, exkludera och jokertecken

Du kan använda jokerteckenen "*", "**" och "?" med attributet Include för att lägga till objekt i en objekttyp. Till exempel

<Photos Include="images\*.jpeg" />

lägger till alla filer med filnamnstillägget .jpeg i mappen bilder till objekttypen Foton, medan

<Photos Include="images\**\*.jpeg" />

lägger till alla filer med filnamnstillägget .jpeg i bilder mapp och alla dess undermappar till objekttypen Foton. Fler exempel finns i Så här: Välj de filer som ska skapas.

Observera att när objekt deklareras läggs de till i objekttypen. Till exempel

<Photos Include="images\*.jpeg" />
<Photos Include="images\*.gif" />

skapar en objekttyp med namnet Foto som innehåller alla filer i mappen bilder med filnamnstillägget .jpeg eller .gif. Dessa rader motsvarar följande rad:

<Photos Include="images\*.jpeg;images\*.gif" />

Du kan exkludera ett objekt från en objekttyp med attributet Exclude. Till exempel

<Compile Include="*.cs" Exclude="*Designer*">

lägger till alla filer med filnamnstillägget .cs till Compile objekttyp, förutom filer vars namn innehåller strängen Designer. För fler exempel, se Hur man: Utesluter filer från bygget.

Attributet Exclude påverkar bara de objekt som läggs till av attributet Include i elementet som innehåller båda objekten. Till exempel

<Compile Include="*.cs" />
<Compile Include="*.res" Exclude="Form1.cs">

skulle inte undanta filen Form1.cs, som lades till i föregående objektelement.

Att inkludera och exkludera objekt

  1. Byt ut Meddelande-uppgiften mot denna rad i kodredigeraren:

    <Message Text="XFiles item type contains @(XFiles)" />
    
  2. Lägg till den här objektgruppen strax efter importelementet:

    <ItemGroup>
       <XFiles Include="*.cs;properties/*.resx" Exclude="*Designer*" />
    </ItemGroup>
    
  3. Spara projektfilen.

  4. Från -kommandofönstretanger du och kör den här raden:

    msbuild buildapp.csproj -t:HelloWorld
    
  5. Granska utdata. Du bör se den här raden:

    XFiles item type contains Form1.cs;Program.cs;Properties/Resources.resx
    

Objektmetadata

Objekt kan innehålla metadata utöver den information som samlas in från attributen Include och Exclude. Uppgifter som kräver mer information om objekt än bara objektvärdet kan använda dessa metadata.

Objektmetadata deklareras i projektfilen genom att skapa ett element med namnet på metadata som ett underordnat element i objektet. Ett objekt kan ha noll eller fler metadatavärden. Följande CSFile-objekt har till exempel Kulturmetadata med värdet "Fr":

<ItemGroup>
    <CSFile Include="main.cs">
        <Culture>Fr</Culture>
    </CSFile>
</ItemGroup>

Om du vill hämta metadatavärdet för en objekttyp använder du följande syntax, där ItemType är namnet på objekttypen och MetaDataName är namnet på metadata:

%(ItemType.MetaDataName)

Så här undersöker du objektmetadata:

  1. Byt ut Meddelande-uppgiften mot denna rad i kodredigeraren:

    <Message Text="Compile.DependentUpon: %(Compile.DependentUpon)" />
    
  2. Spara projektfilen.

  3. Från -kommandofönstretanger du och kör den här raden:

    msbuild buildapp.csproj -t:HelloWorld
    
  4. Granska utdata. Du bör se följande rader:

    Compile.DependentUpon:
    Compile.DependentUpon: Form1.cs
    Compile.DependentUpon: Resources.resx
    Compile.DependentUpon: Settings.settings
    

Observera hur frasen "Compile.DependentUpon" visas flera gånger. Användningen av metadata med den här syntaxen inom ett mål orsakar "batchbearbetning". Batchbearbetning innebär att aktiviteterna i målet körs en gång för varje unikt metadatavärde. Batchbearbetning är MSBuild-skriptets motsvarighet till den vanliga programmeringskonstruktionen "foreach loop". Mer information finns i Batching.

Välkända metadata

När ett objekt läggs till i en objektlista tilldelas objektet några välkända metadata. Till exempel returnerar %(Filename) filnamnet för ett objekt. En fullständig lista över välkända metadata finns i Välkända objektmetadata.

Att undersöka välkända metadata:

  1. Byt ut Meddelande-uppgiften mot denna rad i kodredigeraren:

    <Message Text="Compile Filename: %(Compile.Filename)" />
    
  2. Spara projektfilen.

  3. Från -kommandofönstretanger du och kör den här raden:

    msbuild buildapp.csproj -t:HelloWorld
    
  4. Granska utdata. Du bör se följande rader:

    Compile Filename: Form1
    Compile Filename: Form1.Designer
    Compile Filename: Program
    Compile Filename: AssemblyInfo
    Compile Filename: Resources.Designer
    Compile Filename: Settings.Designer
    

Genom att jämföra de föregående två exemplen kan du se att även om inte alla objekt i Compile objekttyp har DependentUpon-metadata, har alla objekt välkända filnamnsmetadata.

Metadatatransformeringar

Objektlistor kan omvandlas till nya objektlistor. Om du vill transformera en objektlista använder du följande syntax, där <ItemType> är namnet på objekttypen och <MetadataName> är namnet på metadata:

@(ItemType -> '%(MetadataName)')

En objektlista med källfiler kan till exempel omvandlas till en samling objektfiler med ett uttryck som @(SourceFiles -> '%(Filename).obj'). Mer information finns i Transformerar.

Transformera objekt med metadata:

  1. Byt ut Meddelande-uppgiften mot denna rad i kodredigeraren:

    <Message Text="Backup files: @(Compile->'%(filename).bak')" />
    
  2. Spara projektfilen.

  3. Från -kommandofönstretanger du och kör den här raden:

    msbuild buildapp.csproj -t:HelloWorld
    
  4. Granska utdata. Du bör se den här raden:

    Backup files: Form1.bak;Form1.Designer.bak;Program.bak;AssemblyInfo.bak;Resources.Designer.bak;Settings.Designer.bak
    

Observera att metadata som uttrycks i den här syntaxen inte orsakar batchbearbetning.

Nästa steg

Om du vill lära dig hur du skapar en enkel projektfil ett steg i taget i Windows kan du prova Skapa en MSBuild-projektfil från grunden.

Om du främst använder .NET SDK, fortsätt läsa i MSBuild-referensen för .NET SDK-projekt.