Tutorial: Uso de MSBuild
MSBuild es la plataforma de compilación para Microsoft y Visual Studio. En este tutorial se presentan los bloques de creación de MSBuild y se muestra cómo escribir, manipular y depurar proyectos de MSBuild. Obtendrá información sobre:
Crear y manipular un archivo de proyecto.
Cómo usar las propiedades de compilación.
Cómo usar elementos de compilación.
Puede ejecutar MSBuild desde Visual Studio o desde la ventana de comandos de . En este tutorial, creará un archivo de proyecto de MSBuild mediante Visual Studio. Edita el archivo de proyecto en Visual Studio y usa la Ventana de comandos para compilar el proyecto y examinar los resultados.
Instalación de MSBuild
Si tiene Visual Studio, ya tiene INSTALADO MSBuild. Con Visual Studio 2019 y versiones posteriores, se instala en la carpeta de instalación de Visual Studio. Para una instalación predeterminada típica en Windows 10, MSBuild.exe se encuentra en la carpeta de instalación de MSBuild\Current\Bin.
En el instalador, asegúrese de que las herramientas de MSBuild para las cargas de trabajo que use están seleccionadas y elija Instalar.
Para instalar MSBuild en un sistema que no tiene Visual Studio, vaya a Build Tools for Visual Studio 2019, o instale el SDK de .NET .
Si tiene Visual Studio, ya tiene INSTALADO MSBuild. Con Visual Studio 2022, se instala en la carpeta de instalación de Visual Studio. Para una instalación predeterminada típica en Windows 10, MSBuild.exe se encuentra en la carpeta de instalación de MSBuild\Current\Bin.
En el instalador de Visual Studio, vaya a Componentes Individualesy busque la casilla de verificación de MSBuild. Se selecciona automáticamente al elegir cualquiera de las demás cargas de trabajo que se van a instalar.
Para instalar MSBuild en un sistema que no tiene Visual Studio, vaya a Herramientas de compilación para Visual Studio 2022 en la página de descargas. Otra manera de obtener MSBuild es instalar el .NET SDK .
Creación de un proyecto de MSBuild
El sistema de proyectos de Visual Studio se basa en MSBuild. Es fácil crear un nuevo archivo de proyecto mediante Visual Studio. En esta sección, creará un archivo de proyecto de C#. En su lugar, puede crear un archivo de proyecto de Visual Basic. En el contexto de este tutorial, la diferencia entre los dos archivos de proyecto es menor.
Para crear un archivo de proyecto
Abra Visual Studio y cree un proyecto:
En el cuadro de búsqueda, escriba
winforms
y elija Crear una nueva aplicación de Windows Forms (.NET Framework). En el cuadro de diálogo que aparece, elija Crear.En el cuadro Nombre del proyecto, escriba
BuildApp
. Escriba una ubicación para la solución, por ejemplo, D:\.Haga clic en Aceptar o Crear para crear el archivo de proyecto.
Examen del archivo de proyecto
En la sección anterior, usó Visual Studio para crear un archivo de proyecto de C#. El archivo de proyecto se representa en Explorador de soluciones por el nodo del proyecto denominado BuildApp. Puede usar el editor de código de Visual Studio para examinar el archivo del proyecto.
Examinar el archivo de proyecto
En Explorador de Soluciones, haga clic en el Nodo del Proyecto BuildApp.
En el navegador de Propiedades, observe que la propiedad Project File es BuildApp.csproj. Todos los archivos de proyecto se denominan con el sufijo proj. Si hubiera creado un proyecto de Visual Basic, el nombre del archivo del proyecto sería BuildApp.vbproj.
Vuelva a hacer clic con el botón derecho en el nodo del proyecto y, a continuación, haga clic en Editar buildApp.csproj.
El archivo del proyecto aparece en el editor de código.
Nota
Para algunos tipos de proyecto, como C++, debe descargar el proyecto (haga clic con el botón derecho en el archivo del proyecto y elija Descargar proyecto) para poder abrir y editar el archivo del proyecto.
Destinos y tareas
Los archivos de proyecto tienen formato XML con el nodo raíz Project.
La mayoría de los proyectos de .NET tienen un atributo Sdk
. Estos proyectos se denominan proyectos de estilo SDK. Hacer referencia a un SDK significa que MSBuild importa un conjunto de archivos que proporcionan la infraestructura de compilación para ese SDK. Si no hace referencia a ningún SDK, todavía puede usar MSBuild, simplemente no tendrá todas las propiedades y destinos específicos del SDK disponibles automáticamente.
<Project Sdk="Microsoft.NET.Sdk">
Hay muchas variaciones de los SDK de .NET para fines especiales; se describen en SDKs de proyectos de .NET.
El trabajo de construir una aplicación se realiza con los elementos Objetivo y Tarea.
Una tarea es la unidad de trabajo más pequeña; dicho de otro modo, el "átomo" de un proceso de construcción. Las tareas son componentes ejecutables independientes, que pueden tener entradas y salidas. Actualmente no hay ninguna tarea a la que se hace referencia o se define en el archivo del proyecto. Agregue tareas al archivo del proyecto en las secciones siguientes. Para obtener más información, vea Tasks.
Un objetivo es una secuencia de tareas con nombre. Puede ser una secuencia de tareas con nombre, pero, de manera crítica, representa algo que se va a construir o hacer, por lo que debe definirse orientada a objetivos. Para obtener más información, consulte Destinos.
El destino predeterminado no está definido en el archivo del proyecto. En su lugar, se especifica en proyectos importados. El elemento import especifica los proyectos importados. Por ejemplo, en un proyecto de C#, el destino predeterminado se importa desde el archivo Microsoft.CSharp.targets.
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Los archivos importados se insertan eficazmente en el archivo del proyecto donde se hace referencia a ellos.
En los proyectos de estilo SDK, no ve este elemento de importación, ya que el atributo SDK hace que este archivo se importe implícitamente.
MSBuild realiza un seguimiento de los objetivos de una compilación y garantiza que cada objetivo se compila no más de una vez.
Agregar un destino y una tarea
Agregue un destino al archivo del proyecto. Agregue una tarea al destino que imprime un mensaje.
Para agregar un destino y una tarea
Agregue estas líneas al archivo del proyecto, justo después de la instrucción Import o del elemento Project de apertura.
<Target Name="HelloWorld"> </Target>
Este código crea un destino denominado HelloWorld. Tenga en cuenta que tiene compatibilidad con IntelliSense al editar el archivo del proyecto.
Agregue líneas al objetivo HelloWorld para que la sección resultante se vea así:
<Target Name="HelloWorld"> <Message Text="Hello"></Message> <Message Text="World"></Message> </Target>
Guarde el archivo del proyecto.
La tarea Message
es una de las muchas tareas que se incluyen con MSBuild. Para obtener una lista completa de las tareas disponibles y la información de uso, consulte Referencia de tareas.
La tarea Message
toma el valor de cadena del atributo Text
como entrada y lo muestra en el dispositivo de salida (o lo escribe en uno o varios registros, si procede). El destino HelloWorld
ejecuta la tarea de Mensaje dos veces: primero para mostrar "Hola" y, a continuación, para mostrar "Mundo".
Compilación del destino
Si intenta compilar este proyecto desde Visual Studio, no compila el destino que definió. Esto se debe a que Visual Studio elige el destino predeterminado, que sigue siendo el del archivo .targets
importado.
Ejecute MSBuild desde el Símbolo del sistema para desarrolladores de Visual Studio para compilar el destino HelloWorld definido anteriormente. Utilice el conmutador de línea de comandos -target
o -t
para seleccionar el destino.
Nota
Haremos referencia al Símbolo del sistema para desarrolladores como la ventana Comandos en las secciones siguientes.
Para compilar el destino:
Abra la ventana de comando .
En el cuadro de búsqueda de la barra de tareas, empiece a escribir el nombre de la herramienta, como
dev
odeveloper command prompt
. Aparece una lista de aplicaciones instaladas que coinciden con el patrón de búsqueda.Si necesita encontrarlo manualmente, el archivo se LaunchDevCmd.bat en la carpeta {Carpeta de instalación de Visual Studio}\Common7\Tools.
En la ventana de comandos, vaya a la carpeta que contiene el archivo del proyecto, en este caso, D:\BuildApp\BuildApp.
Ejecute msbuild con el modificador de comandos
-t:HelloWorld
. Este comando selecciona y compila el objetivo HelloWorld.msbuild buildapp.csproj -t:HelloWorld
Examine la salida en la ventana Comandos. Debería ver las dos líneas "Hola" y "Mundo".
Hello World
Nota
Si en su lugar ve The target "HelloWorld" does not exist in the project
, probablemente olvidó guardar el archivo del proyecto en el editor de código. Guarde el archivo e inténtelo de nuevo.
Al alternar entre el editor de código y la ventana de comandos, puede cambiar el archivo del proyecto y ver rápidamente los resultados.
Propiedades de compilación
Las propiedades de compilación son pares de nombre y valor que guían la compilación. Ya se han definido varias propiedades de compilación en la parte superior del archivo del proyecto:
<PropertyGroup>
...
<ProductVersion>10.0.11107</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{30E3C9D5-FD86-4691-A331-80EA5BA7E571}</ProjectGuid>
<OutputType>WinExe</OutputType>
...
</PropertyGroup>
Todas las propiedades son elementos secundarios de los elementos PropertyGroup. El nombre de la propiedad es el nombre del elemento secundario, y el valor de la propiedad es el elemento de texto del elemento secundario. Por ejemplo
<TargetFrameworkVersion>net8.0</TargetFrameworkVersion>
define la propiedad denominada TargetFrameworkVersion
, lo que le proporciona el valor de cadena "net8.0".
Las propiedades de compilación se pueden redefinir en cualquier momento. Si
<TargetFrameworkVersion>net6.0</TargetFrameworkVersion>
aparece más adelante en el archivo del proyecto o en un archivo importado más adelante en el archivo del proyecto y, a continuación, TargetFrameworkVersion
toma el nuevo valor "net6.0".
Examen del valor de una propiedad
Para obtener el valor de una propiedad, use la sintaxis siguiente, donde PropertyName
es el nombre de la propiedad:
$(PropertyName)
Use esta sintaxis para examinar algunas de las propiedades del archivo de proyecto.
Para examinar el valor de una propiedad
En el editor de código, reemplace el destino HelloWorld por este código:
<Target Name="HelloWorld"> <Message Text="Configuration is $(Configuration)" /> <Message Text="MSBuildToolsPath is $(MSBuildToolsPath)" /> </Target>
Guarde el archivo del proyecto.
En la ventana comando, escriba y ejecute esta línea:
msbuild buildapp.csproj -t:HelloWorld
Examine la salida. Debería ver estas dos líneas (la salida puede diferir):
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
Propiedades condicionales
Muchas propiedades como Configuration
se definen condicionalmente, es decir, el atributo Condition
aparece en el elemento de propiedad. Las propiedades condicionales se definen o vuelven a definirse solo si la condición se evalúa como "true". Las propiedades no definidas reciben el valor predeterminado de una cadena vacía. Por ejemplo
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
significa «Si aún no se ha definido la propiedad Configuration, defínala y asígnele el valor "Debug".»
Casi todos los elementos de MSBuild pueden tener un atributo Condition
. Para obtener más información sobre el uso del atributo Condition
, consulte Condiciones.
Propiedades reservadas
MSBuild reserva algunos nombres de propiedad para almacenar información sobre el archivo del proyecto y los archivos binarios de MSBuild. MSBuildToolsPath es un ejemplo de una propiedad reservada. Se hace referencia a las propiedades reservadas con la notación $
como cualquier otra propiedad. Para más información, consulte Cómo: Hacer referencia al nombre o la ubicación del archivo del proyecto y Propiedades reservadas y conocidas de MSBuild.
Variables de entorno
Puede hacer referencia a variables de entorno en archivos de proyecto de la misma manera que las propiedades de compilación. Por ejemplo, para usar la variable de entorno PATH
en el archivo de proyecto, use $(Path
). Si el proyecto contiene una definición de propiedad que tiene el mismo nombre que una variable de entorno, la propiedad del proyecto invalida el valor de la variable de entorno. Para obtener más información, consulte Uso de variables de entorno en una compilación.
Establecimiento de propiedades desde la línea de comandos
Las propiedades se pueden definir en la línea de comandos mediante el modificador de línea de comandos -property
o -p
. Los valores de propiedad recibidos de la línea de comandos invalidan los valores de propiedad establecidos en el archivo del proyecto y las variables de entorno.
Para establecer un valor de propiedad desde la línea de comandos:
En la ventana comando, escriba y ejecute esta línea:
msbuild buildapp.csproj -t:HelloWorld -p:Configuration=Release
Examine la salida. Debería ver esta línea:
Configuration is Release.
MSBuild crea la propiedad Configuration y le proporciona el valor "Release".
Caracteres especiales
Algunos caracteres tienen un significado especial en los archivos de proyecto de MSBuild. Algunos ejemplos de estos caracteres incluyen punto y coma (;
) y asteriscos (*
). Para usar estos caracteres especiales como literales en un archivo de proyecto, deben especificarse mediante la sintaxis %<xx>
, donde <xx>
representa el valor hexadecimal ASCII del carácter.
Cambie la tarea Message para mostrar el valor de la propiedad Configuration con caracteres especiales para que se pueda leer mejor.
Para utilizar caracteres especiales en la tarea Message:
En el editor de código, reemplace ambas tareas Message por esta línea:
<Message Text="%24(Configuration) is %22$(Configuration)%22" />
Guarde el archivo del proyecto.
En la ventana comando, escriba y ejecute esta línea:
msbuild buildapp.csproj -t:HelloWorld
Examine la salida. Debería ver esta línea:
$(Configuration) is "Debug"
Para obtener más información, consulte los caracteres especiales de MSBuild .
Elementos de compilación
Un elemento es un fragmento de información, normalmente un nombre de archivo, que se usa como entrada para el sistema de compilación. Por ejemplo, una colección de elementos que representan archivos de origen se puede pasar a una tarea denominada Compilar para compilarlos en un ensamblado.
Todos los elementos son elementos secundarios de elementos ItemGroup. El nombre del elemento es el nombre del elemento secundario y el valor del elemento es el valor del atributo Include del elemento secundario. Los valores de los elementos con el mismo nombre se recopilan en tipos de elemento de ese nombre. Por ejemplo
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
define un grupo de elementos que contiene dos elementos. El tipo de elemento Compile tiene dos valores: Program.cs y Properties\AssemblyInfo.cs.
El código siguiente crea el mismo tipo de elemento declarando ambos archivos en un atributo Include
, separados por punto y coma.
<ItemGroup>
<Compile Include="Program.cs;Properties\AssemblyInfo.cs" />
</ItemGroup>
Para obtener más información, consulte Elementos.
Nota
Las rutas de acceso de archivo son relativas a la carpeta que contiene el archivo de proyecto de MSBuild, incluso si el archivo del proyecto es un archivo de proyecto importado. Hay algunas excepciones a esto, como al usar los elementos Import y UsingTask.
Examen de los valores de tipo de elemento
Para obtener los valores de un tipo de elemento, use la sintaxis siguiente, donde ItemType
es el nombre del tipo de elemento:
@(ItemType)
Use esta sintaxis para examinar el tipo de elemento Compile
en el archivo de proyecto.
Para examinar los valores de tipo de elemento:
En el editor de código, reemplace la tarea de destino HelloWorld por este código:
<Target Name="HelloWorld"> <Message Text="Compile item type contains @(Compile)" /> </Target>
Guarde el archivo del proyecto.
En la ventana comando, escriba y ejecute esta línea:
msbuild buildapp.csproj -t:HelloWorld
Examine la salida. Deberías ver esta larga línea:
Compile item type contains Form1.cs;Form1.Designer.cs;Program.cs;Properties\AssemblyInfo.cs;Properties\Resources.Designer.cs;Properties\Settings.Designer.cs
Los valores de un tipo de elemento se separan con punto y coma de forma predeterminada.
Para cambiar el separador de un tipo de elemento, use la sintaxis siguiente, donde ItemType es el tipo de elemento y Separator es una cadena de uno o varios caracteres de separación:
@(ItemType, Separator)
Cambie la tarea Message
para utilizar retornos de carro y saltos de línea (% 0A%0D) con el fin de mostrar los elementos Compile uno por línea.
Mostrar valores de tipo de elemento uno por línea
En el editor de código, reemplace la tarea Mensaje por esta línea:
<Message Text="Compile item type contains @(Compile, '%0A%0D')" />
Guarde el archivo del proyecto.
En la ventana comando, escriba y ejecute esta línea:
msbuild buildapp.csproj -t:HelloWorld
Examine la salida. Debería ver estas líneas:
Compile item type contains Form1.cs Form1.Designer.cs Program.cs Properties\AssemblyInfo.cs Properties\Resources.Designer.cs Properties\Settings.Designer.cs
Include, Exclude y caracteres comodín
Puede usar los caracteres comodín "*", "**" y "?" con el atributo Include
para agregar elementos a un tipo de elemento. Por ejemplo
<Photos Include="images\*.jpeg" />
agrega todos los archivos con la extensión de archivo .jpeg en la carpeta imágenes al tipo de elemento Photos, mientras que
<Photos Include="images\**\*.jpeg" />
agrega todos los archivos con la extensión de archivo .jpeg en la carpeta imágenes, y todas sus subcarpetas, al tipo de elemento Photos. Para obtener más ejemplos, vea Cómo: Seleccionar los archivos para compilar.
Observe que, a medida que los elementos se declaran, se agregan al tipo de elemento. Por ejemplo
<Photos Include="images\*.jpeg" />
<Photos Include="images\*.gif" />
crea un tipo de elemento denominado Photo que contiene todos los archivos de la carpeta imágenes con una extensión de archivo de .jpeg
o .gif
. Estas líneas son equivalentes a la línea siguiente:
<Photos Include="images\*.jpeg;images\*.gif" />
Puede excluir un elemento de un tipo de elemento con el atributo Exclude
. Por ejemplo
<Compile Include="*.cs" Exclude="*Designer*">
agrega todos los archivos con la extensión de archivo .cs al tipo de elemento Compile
, excepto los archivos cuyos nombres contienen la cadena Designer. Para obtener más ejemplos, vea Cómo: Excluir archivos de la compilación.
El atributo Exclude
solo afecta a los elementos agregados por el atributo Include
en el elemento item que los contiene ambos. Por ejemplo
<Compile Include="*.cs" />
<Compile Include="*.res" Exclude="Form1.cs">
no excluiría el archivo Form1.cs, que se agregó en el elemento anterior.
Incluir y excluir elementos
En el editor de código, reemplace la tarea Mensaje por esta línea:
<Message Text="XFiles item type contains @(XFiles)" />
Agregue este grupo de elementos justo después del elemento Import:
<ItemGroup> <XFiles Include="*.cs;properties/*.resx" Exclude="*Designer*" /> </ItemGroup>
Guarde el archivo del proyecto.
En la ventana comando, escriba y ejecute esta línea:
msbuild buildapp.csproj -t:HelloWorld
Examine la salida. Debería ver esta línea:
XFiles item type contains Form1.cs;Program.cs;Properties/Resources.resx
Metadatos de elementos
Los elementos pueden contener metadatos además de la información recopilada de los atributos Include
y Exclude
. Las tareas que requieren más información sobre los elementos que solo el valor del elemento pueden usar estos metadatos.
Los metadatos de elemento se declaran en el archivo de proyecto mediante la creación de un elemento con el nombre de los metadatos como un elemento secundario del elemento. Un elemento puede tener cero o más valores de metadatos. Por ejemplo, el siguiente elemento de CSFile tiene metadatos de referencia cultural con un valor de "Fr":
<ItemGroup>
<CSFile Include="main.cs">
<Culture>Fr</Culture>
</CSFile>
</ItemGroup>
Para obtener el valor de metadatos de un tipo de elemento, use la sintaxis siguiente, donde ItemType
es el nombre del tipo de elemento y MetaDataName es el nombre de los metadatos:
%(ItemType.MetaDataName)
Para examinar los metadatos del elemento:
En el editor de código, reemplace la tarea Mensaje por esta línea:
<Message Text="Compile.DependentUpon: %(Compile.DependentUpon)" />
Guarde el archivo del proyecto.
En la ventana comando, escriba y ejecute esta línea:
msbuild buildapp.csproj -t:HelloWorld
Examine la salida. Debería ver estas líneas:
Compile.DependentUpon: Compile.DependentUpon: Form1.cs Compile.DependentUpon: Resources.resx Compile.DependentUpon: Settings.settings
Observe cómo aparece la frase "Compile.DependentUpon" varias veces. El uso de metadatos con esta sintaxis dentro de un destino provoca "procesamiento por lotes". El procesamiento por lotes significa que las tareas dentro del destino se ejecutan una vez para cada valor de metadatos único. El procesamiento por lotes es el equivalente del script de MSBuild de la construcción de programación "bucle foreach" común. Para obtener más información, consulte Procesamiento por lotes.
Metadatos conocidos
Cada vez que se agrega un elemento a una lista de elementos, a ese elemento se le asignan algunos metadatos conocidos. Por ejemplo, %(Filename)
devuelve el nombre de archivo de cualquier elemento. Para obtener una lista completa de los metadatos de elementos bien conocidos, consulte Metadatos de elementos bien conocidos.
Para examinar los metadatos conocidos:
En el editor de código, reemplace la tarea Mensaje por esta línea:
<Message Text="Compile Filename: %(Compile.Filename)" />
Guarde el archivo del proyecto.
En la ventana comando, escriba y ejecute esta línea:
msbuild buildapp.csproj -t:HelloWorld
Examine la salida. Debería ver estas líneas:
Compile Filename: Form1 Compile Filename: Form1.Designer Compile Filename: Program Compile Filename: AssemblyInfo Compile Filename: Resources.Designer Compile Filename: Settings.Designer
Al comparar los dos ejemplos anteriores, puede ver que, aunque no todos los elementos del tipo de elemento de Compile
tienen metadatos DependentUpon, todos los elementos tienen los bien conocidos metadatos de NombreDeArchivo.
Transformaciones de metadatos
Las listas de elementos se pueden transformar en nuevas listas de elementos. Para transformar una lista de elementos, use la sintaxis siguiente, donde <ItemType>
es el nombre del tipo de elemento y <MetadataName>
es el nombre de los metadatos:
@(ItemType -> '%(MetadataName)')
Por ejemplo, una lista de elementos de archivos de origen se puede transformar en una colección de archivos de objeto mediante una expresión como @(SourceFiles -> '%(Filename).obj')
. Para obtener más información, consulte Transformaciones.
Para transformar elementos mediante metadatos:
En el editor de código, reemplace la tarea Mensaje por esta línea:
<Message Text="Backup files: @(Compile->'%(filename).bak')" />
Guarde el archivo del proyecto.
En la ventana comando, escriba y ejecute esta línea:
msbuild buildapp.csproj -t:HelloWorld
Examine la salida. Debería ver esta línea:
Backup files: Form1.bak;Form1.Designer.bak;Program.bak;AssemblyInfo.bak;Resources.Designer.bak;Settings.Designer.bak
Observe que los metadatos expresados en esta sintaxis no provocan el procesamiento por lotes.
Pasos siguientes
Para obtener información sobre cómo crear un archivo de proyecto simple de un paso a la vez, en Windows, pruebe Crear un archivo de proyecto de MSBuild desde cero.
Si usa principalmente el SDK de .NET, siga leyendo en Referencia de MSBuild para proyectos del SDK de .NET.