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.
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
Öppna Visual Studio och skapa ett projekt:
I sökrutan skriver du
winforms
och 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:\.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
I Solution Explorerklickar du på projektnoden BuildApp.
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.
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
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.
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>
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:
Öppna kommandofönstret .
I sökrutan i aktivitetsfältet börjar du skriva namnet på verktyget, till exempel
dev
ellerdeveloper 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.
I kommandofönstret navigerar du till mappen som innehåller projektfilen, i det här fallet D:\BuildApp\BuildApp.
Kör msbuild med kommandoväxeln
-t:HelloWorld
. Det här kommandot väljer och skapar HelloWorld-målet:msbuild buildapp.csproj -t:HelloWorld
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
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>
Spara projektfilen.
Från -kommandofönstretanger du och kör den här raden:
msbuild buildapp.csproj -t:HelloWorld
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:
Från -kommandofönstretanger du och kör den här raden:
msbuild buildapp.csproj -t:HelloWorld -p:Configuration=Release
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:
Ersätt båda meddelandeuppgifterna i kodredigeraren med den här raden:
<Message Text="%24(Configuration) is %22$(Configuration)%22" />
Spara projektfilen.
Från -kommandofönstretanger du och kör den här raden:
msbuild buildapp.csproj -t:HelloWorld
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:
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>
Spara projektfilen.
Från -kommandofönstretanger du och kör den här raden:
msbuild buildapp.csproj -t:HelloWorld
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
Byt ut Meddelande-uppgiften mot denna rad i kodredigeraren:
<Message Text="Compile item type contains @(Compile, '%0A%0D')" />
Spara projektfilen.
Från -kommandofönstretanger du och kör den här raden:
msbuild buildapp.csproj -t:HelloWorld
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
Byt ut Meddelande-uppgiften mot denna rad i kodredigeraren:
<Message Text="XFiles item type contains @(XFiles)" />
Lägg till den här objektgruppen strax efter importelementet:
<ItemGroup> <XFiles Include="*.cs;properties/*.resx" Exclude="*Designer*" /> </ItemGroup>
Spara projektfilen.
Från -kommandofönstretanger du och kör den här raden:
msbuild buildapp.csproj -t:HelloWorld
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:
Byt ut Meddelande-uppgiften mot denna rad i kodredigeraren:
<Message Text="Compile.DependentUpon: %(Compile.DependentUpon)" />
Spara projektfilen.
Från -kommandofönstretanger du och kör den här raden:
msbuild buildapp.csproj -t:HelloWorld
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:
Byt ut Meddelande-uppgiften mot denna rad i kodredigeraren:
<Message Text="Compile Filename: %(Compile.Filename)" />
Spara projektfilen.
Från -kommandofönstretanger du och kör den här raden:
msbuild buildapp.csproj -t:HelloWorld
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:
Byt ut Meddelande-uppgiften mot denna rad i kodredigeraren:
<Message Text="Backup files: @(Compile->'%(filename).bak')" />
Spara projektfilen.
Från -kommandofönstretanger du och kör den här raden:
msbuild buildapp.csproj -t:HelloWorld
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.