Esercitazione: Usare MSBuild

MSBuild è la piattaforma di compilazione per Microsoft e Visual Studio. Questa esercitazione presenta i blocchi predefiniti di MSBuild e illustra come scrivere, modificare ed eseguire il debug di progetti MSBuild. Vengono fornite informazioni su:

  • Creazione e modifica di un file di progetto.

  • Come usare le proprietà di compilazione.

  • Come usare gli elementi di compilazione.

È possibile eseguire MSBuild da Visual Studio o dalla finestra di comando. In questa esercitazione viene creato un file di progetto MSBuild usando Visual Studio. Si modifica il file di progetto in Visual Studio e si usa la finestra di comando per compilare il progetto ed esaminare i risultati.

Installare MSBuild

Se Visual Studio è già installato, MSBuild è già installato. Con Visual Studio 2019 e versioni successive, viene installato nella cartella di installazione di Visual Studio. Per un'installazione predefinita tipica in Windows 10, MSBuild.exe si trova nella cartella di installazione in MSBuild\Current\Bin.

Nel programma di installazione verificare che gli strumenti di MSBuild per i carichi di lavoro usati siano selezionati e scegliere Installa.

Installing MSBuild

Per installare MSBuild in un sistema che non dispone di Visual Studio, passare a Build Tools for Visual Studio 2019 o installare .NET SDK.

Se Visual Studio è già installato, MSBuild è già installato. Con Visual Studio 2022, viene installato nella cartella di installazione di Visual Studio. Per un'installazione predefinita tipica in Windows 10, MSBuild.exe si trova nella cartella di installazione in MSBuild\Current\Bin.

Nel programma di installazione di Visual Studio passare a Singoli componenti e individuare la casella di controllo per MSBuild. Viene selezionato automaticamente quando si sceglie uno degli altri carichi di lavoro da installare.

Per installare MSBuild in un sistema che non dispone di Visual Studio, passare a Build Tools for Visual Studio 2022 (Strumenti di compilazione per Visual Studio 2022) nella pagina di download. Un altro modo per ottenere MSBuild consiste nell'installare .NET SDK.

Creare un progetto MSBuild

Il sistema dei progetti di Visual Studio si basa su MSBuild. È facile creare un nuovo file di progetto usando Visual Studio. In questa sezione viene creato un file di progetto C#. È possibile scegliere di creare invece un file di progetto Visual Basic. Nel contesto di questa esercitazione, la differenza tra i due file di progetto è secondaria.

Per creare un file di progetto

  1. Aprire Visual Studio e creare un progetto:

    Nella casella di ricerca digitare winforms, quindi scegliere Crea una nuova app Windows Form (.NET Framework). Nella finestra di dialogo visualizzata scegliere Crea.

    Nella casella Nome progetto digitare BuildApp. Immettere un percorso per la soluzione, ad esempio D:\.

  2. Fare clic su OK o su Crea per creare il file di progetto.

Esaminare il file di progetto

Nella sezione precedente è stato usato Visual Studio per creare un file di progetto C#. Il file di progetto è rappresentato in Esplora soluzioni dal nodo del progetto denominato BuildApp. È possibile usare l'editor Visual Studio Code per esaminare il file di progetto.

Per esaminare il file di progetto

  1. In Esplora soluzioni fare clic sul nodo del progetto BuildApp.

  2. Nel browser Proprietà si noti che la proprietà File di progetto corrisponde a BuildApp.csproj. Il nome di tutti i file di progetto ha il suffisso proj. Se si è creato un progetto Visual Basic, il nome del file di progetto è BuildApp.vbproj.

  3. Fare ancora clic con il pulsante destro del mouse sul nodo del progetto, quindi scegliere Modifica BuildApp.csproj.

    Il file di progetto verrà visualizzato nell'editor del codice.

Nota

Per alcuni tipi di progetto, ad esempio C++, è necessario scaricare il progetto (fare clic con il pulsante destro del mouse sul file di progetto e scegliere Scarica progetto) prima di poter aprire e modificare il file di progetto.

Destinazioni e attività

I file di progetto sono file in formato XML con il nodo radice Project.

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0"  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

La maggior parte dei progetti .NET ha un Sdk attributo . Questi progetti sono denominati progetti in stile SDK.

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

Esistono molte varianti di .NET SDK per scopi speciali; sono descritti in .NET Project SDK.

La compilazione di un'applicazione viene eseguita con gli elementi Target e Task.

  • Un'attività è la più piccola unità di lavoro, in altre parole, l'"atom" di una compilazione. Le attività sono componenti eseguibili indipendenti, che possono avere input e output. Attualmente nel file di progetto non sono presenti attività definite o a cui si fa riferimento. Aggiungere attività al file di progetto nelle sezioni seguenti. Per altre informazioni, vedere Tasks (Attività).

  • Una destinazione è una sequenza denominata di attività. Potrebbe trattarsi di una sequenza denominata di attività, ma in modo critico, rappresenta un elemento da compilare o eseguire, quindi deve essere definito in modo orientato agli obiettivi. Per altre informazioni, vedere Destinazioni.

La destinazione predefinita non è definita nel file di progetto. Viene invece specificato nei progetti importati. L'elemento Import specifica i progetti importati. In un progetto C#, ad esempio, la destinazione predefinita viene importata dal file Microsoft.CSharp.targets.

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

I file importati vengono inseriti nel file di progetto ovunque vi si faccia riferimento.

Nei progetti in stile SDK questo elemento di importazione non viene visualizzato, poiché l'attributo SDK causa l'importazione implicita di questo file.

MSBuild tiene traccia delle destinazioni di una compilazione e garantisce che ogni destinazione non venga compilata più di una volta.

Aggiungere una destinazione e un'attività

Aggiungere una destinazione al file di progetto. Aggiungere un'attività alla destinazione che stampa un messaggio.

Per aggiungere una destinazione e un'attività

  1. Aggiungere queste righe al file di progetto subito dopo l'istruzione Import o l'elemento Project di apertura.

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

    Questo codice crea una destinazione denominata HelloWorld. Si noti che è disponibile il supporto di IntelliSense durante la modifica del file di progetto.

  2. Aggiungere righe alla destinazione HelloWorld in modo che la sezione risultante sia simile alla seguente:

    <Target Name="HelloWorld">
      <Message Text="Hello"></Message>  <Message Text="World"></Message>
    </Target>
    
  3. Salvare il file di progetto.

L'attività Message è una delle numerose attività disponibili con MSBuild. Per un elenco completo delle attività disponibili e per informazioni sull'utilizzo, vedere Informazioni di riferimento sull'attività.

L'attività Message accetta il valore stringa dell'attributo Text come input e lo visualizza nel dispositivo di output (o lo scrive in uno o più log, se applicabile). La destinazione HelloWorld esegue due volte l'attività Messaggio: prima per visualizzare "Hello" e quindi per visualizzare "World".

Compilare la destinazione

Se si tenta di compilare questo progetto da Visual Studio, non viene compilata la destinazione definita. Questo perché Visual Studio sceglie la destinazione predefinita, che è ancora quella nel file importato .targets .

Eseguire MSBuild dal prompt dei comandi per gli sviluppatori per Visual Studio per compilare la destinazione HelloWorld definita in precedenza. Usare l'opzione della riga di comando -target o -t per selezionare la destinazione.

Nota

Si farà riferimento al prompt dei comandi per gli sviluppatori come finestra di comando nelle sezioni seguenti.

Per compilare la destinazione:

  1. Aprire la finestra di comando.

    Nella casella di ricerca della barra delle applicazioni iniziare a digitare il nome dello strumento, ad esempio dev o developer command prompt. Verrà visualizzato un elenco di app installate che corrispondono ai criteri di ricerca.

    Se è necessario trovarlo manualmente, il file è LaunchDevCmd.bat nella cartella {Visual Studio installation}\Common7\Tools .

  2. Dalla finestra di comando passare alla cartella contenete il file di progetto, in questo caso D:\BuildApp\BuildApp.

  3. Eseguire msbuild con l'opzione -t:HelloWorlddi comando . Questo comando seleziona e compila la destinazione HelloWorld:

    msbuild buildapp.csproj -t:HelloWorld
    
  4. Esaminare l'output nella finestra di comando. Saranno visualizzate le due righe "Hello" e "World":

    Hello
    World
    

Nota

Se invece si visualizza The target "HelloWorld" does not exist in the project, è probabile che si sia dimenticato di salvare il file di progetto nell'editor di codice. Salvare il file e riprovare.

Alternando l'editor di codice e la finestra di comando, è possibile modificare il file di progetto e visualizzare velocemente i risultati.

Proprietà di compilazione

Le proprietà di compilazione sono coppie nome-valore che agevolano la compilazione. Diverse proprietà di compilazione sono già definite all'inizio del file di progetto:

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

Tutte le proprietà sono elementi figlio degli elementi PropertyGroup. Il nome della proprietà è il nome dell'elemento figlio e il valore della proprietà è l'elemento testo dell'elemento figlio. ad esempio:

<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>

definisce la proprietà denominata TargetFrameworkVersion, assegnando il valore stringa "v4.5".

Le proprietà di compilazione possono essere ridefinite in qualsiasi momento. If

<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>

viene visualizzato più avanti nel file di progetto o in un file importato più avanti nel file di progetto, quindi TargetFrameworkVersion accetta il nuovo valore "v3.5".

Esaminare il valore di una proprietà

Per ottenere il valore di una proprietà, usare la sintassi seguente, dove PropertyName è il nome della proprietà:

$(PropertyName)

Usare questa sintassi per esaminare alcune delle proprietà nel file di progetto.

Per esaminare un valore di proprietà

  1. Nell'editor di codice sostituire la destinazione HelloWorld con questo codice:

    <Target Name="HelloWorld">
      <Message Text="Configuration is $(Configuration)" />
      <Message Text="MSBuildToolsPath is $(MSBuildToolsPath)" />
    </Target>
    
  2. Salvare il file di progetto.

  3. Dalla finestra di comando immettere ed eseguire questa riga:

    msbuild buildapp.csproj -t:HelloWorld
    
  4. Esaminare l'output. Dovrebbero essere visualizzate queste due righe (l'output potrebbe essere diverso):

    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
    

Proprietà condizionali

Molte proprietà come Configuration sono definite in modo condizionale, ovvero l'attributo Condition viene visualizzato nell'elemento della proprietà. Le proprietà condizionali vengono definite o ridefinite solo se la condizione restituisce "true". Alle proprietà non predefinite viene assegnato il valore predefinito di una stringa vuota. ad esempio:

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

significa "Se la proprietà Configuration non è ancora stata definita, definirla e assegnargli il valore "Debug".

Quasi tutti gli elementi di MSBuild possono avere un attributo Condition. Per altre informazioni sull'uso dell'attributo Condition, vedere Condizioni.

Proprietà riservate

In MSBuild alcuni nomi di proprietà sono riservati per archiviare le informazioni relative al file di progetto e ai file binari di MSBuild. MSBuildToolsPath è un esempio di proprietà riservata. Si fa riferimento alle proprietà riservate con la notazione $, come per qualsiasi altra proprietà. Per altre informazioni, vedere Procedura: Fare riferimento al nome o al percorso del file di progetto e Proprietà riservate e note MSBuild.

Variabili di ambiente

È possibile fare riferimento alle variabili di ambiente nei file di progetto come si fa riferimento alle proprietà di compilazione. Ad esempio, per usare la variabile di ambiente PATH nel file di progetto, usare $(Path). Se il progetto contiene una definizione di una proprietà con lo stesso nome di una variabile di ambiente, la proprietà nel progetto esegue l'override del valore della variabile di ambiente. Per altre informazioni, vedere Procedura: Usare le variabili di ambiente in una compilazione.

Impostare le proprietà dalla riga di comando

Le proprietà possono essere definite nella riga di comando usando l'opzione della riga di comando -property o -p. I valori delle proprietà ricevuti dalla riga di comando eseguono l'override dei valori delle proprietà impostati nel file di progetto e nelle variabili di ambiente.

Per impostare un valore della proprietà dalla riga di comando:

  1. Dalla finestra di comando immettere ed eseguire questa riga:

    msbuild buildapp.csproj -t:HelloWorld -p:Configuration=Release
    
  2. Esaminare l'output. Dovrebbe essere visualizzata questa riga:

    Configuration is Release.
    

MSBuild crea la proprietà Configuration e assegna il valore "Release".

Caratteri speciali

Alcuni caratteri hanno un significato particolare nei file di progetto di MSBuild. Tra gli esempi di questi caratteri sono inclusi il punto e virgola (;) e l'asterisco (*). Per usare questi caratteri speciali come valori letterali in un file di progetto, è necessario specificarli usando la sintassi %<xx>, dove <xx> rappresenta il valore esadecimale ASCII del carattere.

Modificare l'attività Message per visualizzare il valore della proprietà Configuration con i caratteri speciali per renderla più leggibile.

Per usare caratteri speciali nell'attività Messaggio:

  1. Nell'editor del codice sostituire entrambe le attività Message con questa riga:

    <Message Text="%24(Configuration) is %22$(Configuration)%22" />
    
  2. Salvare il file di progetto.

  3. Dalla finestra di comando immettere ed eseguire questa riga:

    msbuild buildapp.csproj -t:HelloWorld
    
  4. Esaminare l'output. Dovrebbe essere visualizzata questa riga:

    $(Configuration) is "Debug"
    

Per altre informazioni, vedere Caratteri speciali di MSBuild.

Elementi di compilazione

Un elemento è un'informazione, in genere un nome file, usata come input per il sistema di compilazione. Ad esempio, una raccolta di elementi che rappresentano file di origine potrebbe venire passata a un'attività denominata Compile per compilarli in un assembly.

Tutti gli elementi sono elementi figlio degli elementi ItemGroup. Il nome dell'elemento è il nome dell'elemento figlio e il valore dell'elemento è il valore dell'attributo Include dell'elemento figlio. I valori degli elementi con lo stesso nome vengono raccolti in tipi di elemento con tale nome. ad esempio:

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

definisce un gruppo di elementi contenente due elementi. Il tipo di elemento Compile ha due valori: Program.cs e Properties\AssemblyInfo.cs.

Il codice seguente crea lo stesso tipo di elemento dichiarando entrambi i file in un Include attributo, separati da un punto e virgola.

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

Per altre informazioni, vedere Elementi.

Nota

I percorsi dei file sono relativi alla cartella contenente il file di progetto MSBuild, anche se il file di progetto è un file di progetto importato. Esistono alcune eccezioni, ad esempio quando si usano elementi Import e UsingTask .

Esaminare i valori di un tipo di elemento

Per ottenere i valori di un tipo di elemento, usare la sintassi seguente, dove ItemType è il nome del tipo di elemento:

@(ItemType)

Usare questa sintassi per esaminare il Compile tipo di elemento nel file di progetto.

Per esaminare i valori del tipo di elemento:

  1. Nell'editor di codice sostituire l'attività di destinazione HelloWorld con questo codice:

    <Target Name="HelloWorld">
      <Message Text="Compile item type contains @(Compile)" />
    </Target>
    
  2. Salvare il file di progetto.

  3. Dalla finestra di comando immettere ed eseguire questa riga:

    msbuild buildapp.csproj -t:HelloWorld
    
  4. Esaminare l'output. Dovrebbe essere visualizzata questa lunga riga:

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

I valori di un tipo di elemento sono separati da punto e virgola per impostazione predefinita.

Per modificare il separatore di un tipo di elemento, usare la sintassi seguente, dove ItemType è il tipo di elemento e Separator è una stringa di uno o più caratteri di separazione:

@(ItemType, Separator)

Modificare l'attività Message per usare ritorni a capo e avanzamenti riga (%0A%0D) per visualizzare un elemento Compile per riga.

Per visualizzare i valori di un tipo di elemento uno per riga

  1. Nell'editor del codice sostituire l'attività Message con questa riga:

    <Message Text="Compile item type contains @(Compile, '%0A%0D')" />
    
  2. Salvare il file di progetto.

  3. Dalla finestra di comando immettere ed eseguire questa riga:

    msbuild buildapp.csproj -t:HelloWorld
    
  4. Esaminare l'output. Dovrebbero essere visualizzate queste righe:

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

Include, Exclude e caratteri jolly

È possibile usare i caratteri jolly "*", "**" e "?" con l'attributo Include per aggiungere elementi a un tipo di elemento. ad esempio:

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

aggiunge tutti i file con estensione jpeg nella cartella images al tipo di elemento Photos, mentre

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

aggiunge tutti i file con estensione jpeg nella cartella images e in tutte le relative sottocartelle al tipo di elemento Photos. Per altri esempi, vedere Procedura: Selezionare i file da compilare.

Si noti che quando gli elementi vengono dichiarati vengono aggiunti al tipo di elemento. ad esempio:

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

crea un tipo di elemento denominato Photo che contiene tutti i file nella cartella images con estensione di .jpeg file o .gif. Queste righe sono equivalenti alla riga seguente:

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

È possibile escludere un elemento da un tipo di elemento con l'attributo Exclude . ad esempio:

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

aggiunge tutti i file con estensione cs al tipo di elemento Compile, tranne i file i cui nomi contengono la stringa Designer. Per altri esempi, vedere Procedura: Escludere file dalla compilazione.

L'attributo Exclude influisce solo sugli elementi aggiunti dall'attributo Include nell'elemento elemento che li contiene entrambi. ad esempio:

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

non esclude il file Form1.cs, che è stato aggiunto nell'elemento dell'elemento precedente.

Per includere ed escludere elementi

  1. Nell'editor del codice sostituire l'attività Message con questa riga:

    <Message Text="XFiles item type contains @(XFiles)" />
    
  2. Aggiungere questo gruppo di elementi immediatamente dopo l'elemento Import:

    <ItemGroup>
       <XFiles Include="*.cs;properties/*.resx" Exclude="*Designer*" />
    </ItemGroup>
    
  3. Salvare il file di progetto.

  4. Dalla finestra di comando immettere ed eseguire questa riga:

    msbuild buildapp.csproj -t:HelloWorld
    
  5. Esaminare l'output. Dovrebbe essere visualizzata questa riga:

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

Metadati degli elementi

Gli elementi possono contenere metadati oltre alle informazioni raccolte dagli Include attributi e Exclude . Le attività che richiedono più informazioni sugli elementi rispetto al solo valore dell'elemento possono usare questi metadati.

Per dichiarare i metadati degli elementi nel file di progetto, è necessario creare un elemento con il nome dei metadati come elemento figlio dell'elemento. Un elemento può avere zero o più valori di metadati. Ad esempio, l'elemento CSFile seguente contiene metadati Culture con il valore "Fr":

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

Per ottenere il valore dei metadati di un tipo di elemento, usare la sintassi seguente, dove ItemType è il nome del tipo di elemento e MetaDataName è il nome dei metadati:

%(ItemType.MetaDataName)

Per esaminare i metadati degli elementi:

  1. Nell'editor del codice sostituire l'attività Message con questa riga:

    <Message Text="Compile.DependentUpon: %(Compile.DependentUpon)" />
    
  2. Salvare il file di progetto.

  3. Dalla finestra di comando immettere ed eseguire questa riga:

    msbuild buildapp.csproj -t:HelloWorld
    
  4. Esaminare l'output. Dovrebbero essere visualizzate queste righe:

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

Si noti come la frase "Compile.DependentUpon" venga visualizzata più volte. L'uso dei metadati con questa sintassi all'interno di una destinazione causa l'invio in batch. L'invio in batch significa che le attività all'interno della destinazione vengono eseguite una sola volta per ogni valore di metadati univoco. L'invio in batch è l'equivalente dello script MSBuild del costrutto di programmazione comune "ciclo foreach". Per altre informazioni, vedere Batch.

Metadati noti

Quando un elemento viene aggiunto a un elenco di elementi, a tale elemento vengono assegnati alcuni metadati noti. Ad esempio, %(FileName) restituisce il nome file di qualsiasi elemento. Per l'elenco completo dei metadati noti, vedere Metadati noti degli elementi.

Per esaminare i metadati noti:

  1. Nell'editor del codice sostituire l'attività Message con questa riga:

    <Message Text="Compile Filename: %(Compile.Filename)" />
    
  2. Salvare il file di progetto.

  3. Dalla finestra di comando immettere ed eseguire questa riga:

    msbuild buildapp.csproj -t:HelloWorld
    
  4. Esaminare l'output. Dovrebbero essere visualizzate queste righe:

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

Confrontando i due esempi precedenti, è possibile notare che, anche se non tutti gli elementi nel tipo di elemento Compile hanno metadati DependentUpon, tutti gli elementi hanno i metadati filename noti.

Trasformazioni di metadati

Gli elenchi di elementi possono essere trasformati in nuovi elenchi di elementi. Per trasformare un elenco di elementi, usare la sintassi seguente, dove <ItemType> è il nome del tipo di elemento e <MetadataName> è il nome dei metadati:

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

Ad esempio, un elenco di file di origine può essere trasformato in una raccolta di file oggetto usando un'espressione come @(SourceFiles -> '%(Filename).obj'). Per altre informazioni, vedere Trasformazioni.

Per trasformare gli elementi usando i metadati:

  1. Nell'editor del codice sostituire l'attività Message con questa riga:

    <Message Text="Backup files: @(Compile->'%(filename).bak')" />
    
  2. Salvare il file di progetto.

  3. Dalla finestra di comando immettere ed eseguire questa riga:

    msbuild buildapp.csproj -t:HelloWorld
    
  4. Esaminare l'output. Dovrebbe essere visualizzata questa riga:

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

Si noti che i metadati espressi in questa sintassi non causano l'invio in batch.

Passaggi successivi

Per informazioni su come creare un semplice file di progetto un passaggio alla volta, in Windows provare a creare un file di progetto MSBuild da zero.

Se si usa principalmente .NET SDK, continuare a leggere le informazioni di riferimento su MSBuild per i progetti .NET SDK.