Menú de navegaciónMenú
Categorías

La mejor forma de Aprender Programación online y en español www.campusmvp.es

?id=c9e34199-4bfe-45d6-93e5-0df5a8bc99cb

.NET Core / .NET: Cómo publicar aplicaciones en un único ejecutable

Cuando compilas una aplicación con .NET Core de cualquier tipo, tienes dos formas básicas de hacerlo:

  • Generando tan solo los ensamblados propios de tu aplicación y de los componentes que utilicen. En este caso debes estar seguro de que los equipos que van a ejecutar la aplicación tienen instalado el runtime de .NET. Esto es lo que hace por defecto Visual Studio cuando compilas.
  • Incluyendo en el resultado todos los archivos propios de .NET, de modo que el runtime se distribuye con tu aplicación y no es necesario que los usuarios instalen nada. Esto facilita mucho el despliegue a costa de tener que mover un montón de archivos (y "megas").

Da igual la modalidad que escojas: al final acabas con un ejecutable y un número mayor o menor de ensamblados relacionados que vas a necesitar según lo que elijas.

Por ejemplo, para publicar la aplicación sólo con los ensamblados propios basta con que escribas en la línea de comandos (dentro de la carpeta del proyecto) lo siguiente:

dotnet publish -c release -r win10-x64 --self-contained false

Esto generará un ejecutable de tu aplicación para Windows de 64 bits (opción -r) con la configuración "Release" (o sea, para producción: opción -c) y de modo que no sea autosuficiente, por lo que necesitará tener .NET instalado para funcionar. Así que obtendrás tan solo tu ejecutable con los ensamblados que necesite (paquetes NuGet y bibliotecas propias que la acompañen).

Nota: si quieres generar los ejecutables para Linux o para macOS, deberías utilizar -r linux-x64 y -r osx-x64 respectivamente.

Si hubiésemos utilizado --self-contained true se hubiesen incluido también todos los ensamblados de tiempo de ejecución de .NET (runtime), por lo que en nuestra carpeta de publicación tendríamos literalmente cientos de archivos aparte del nuestro.

¿Cómo podemos conseguir un único ejecutable con todo lo necesario?

De esta forma podríamos obtener un único archivo que podríamos enviar con confianza a cualquiera, de modo que, sin necesidad de instalar nada, pueda ejecutar nuestra aplicación. Esto es fenomenal para algunos casos de uso, ya que facilitamos mucho la distribución de la aplicación para que la use cualquiera, basta con descargar un archivo y hacer doble-clic.

Hace poco explicaba cómo puedes conseguir esto mismo con .NET "clásico". Para lograrlo hay que emplear una herramienta especial, ajena a la propia plataforma. Además no se incluyen los propios de .NET, sino tan solo los tuyos.

Sin embargo, en .NET Core ya se ha tenido en cuenta esta posibilidad de serie y no necesitamos nada especial: tan sólo el comando dotnet y usar sus opciones con un poco de habilidad.

En esta ocasión, en lugar de contártelo por escrito, he grabado un vídeo práctico en el que te enseño cómo puedes hacerlo no sólo con aplicaciones de consola o escritorio sino incluso para poder distribuir aplicaciones web autocontenidas, con un único .exe a distribuir para que funcionen:

¡Espero que te resulte útil!

Fecha de publicación:
José Manuel Alarcón Fundador de campusMVP, es ingeniero industrial y especialista en consultoría de empresa. Ha escrito diversos libros, habiendo publicado hasta la fecha cientos de artículos sobre informática e ingeniería en publicaciones especializadas. Microsoft lo ha reconocido como MVP (Most Valuable Professional) en desarrollo web desde el año 2004 hasta la actualidad. Puedes seguirlo en Twitter en @jm_alarcon o leer sus blog técnico o personal. Ver todos los posts de José Manuel Alarcón
Archivado en: Lenguajes y plataformas

Boletín campusMVP.es

Solo cosas útiles. Una vez al mes.

🚀 Únete a miles de desarrolladores

DATE DE ALTA

x No me interesa | x Ya soy suscriptor

La mejor formación online para desarrolladores como tú

Comentarios (10) -

Buenas,
he probado de empaquetar en un solo exe una aplicación de consola, y el proceso también empaqueta el archivo de configuración,  ¿se puede elegir de alguna manera que archivos se empaquetan en el .exe?

Responder

José Manuel Alarcón
José Manuel Alarcón

Hola Ferrán:

Por defecto, todos los archivos que aparezcan en la carpeta de publicación se meten automáticamente dentro del .exe excepto los .pdb (de símbolos depuración). Eso incluye los ajustes.

Si quieres dejar algún archivo fuera lo puedes marcar en el archivo del proyecto (.csproj) con un nodo "ExcludeFromSingleFile" (docs.microsoft.com/.../single-file) pero el .exe resultante no lo leerá ya que lo que hacen estos archivos es descomprimir la app en una carpeta temporal y ejecutarla desde allí, por lo que el exe real no verá tu archivo de configuración.

Estoy de acuerdo con que es un poco chapuza, pero es que la filosofía que han seguido con el ejecutable único es literalmente "único" : todo va dentro de él.

Saludos.

Responder

muchas gracias José

Responder

Hola José,

En primer lugar, muchas gracias por toda la información facilitada.

Perdona que te moleste.
Estoy intentando publicar una solución en Net Core 5 tanto desde visual studio como desde línea de comandos para posteriormente publicar el proyecto en el IIS

Cuando lo realizo desde visual studio me retorna este error:

MSB4018  Error inesperado en la tarea "CopyRefAssembly".
System.InvalidOperationException: La tarea "CopyRefAssembly" no registró sus recursos. Para usar el método "TaskLoggingHelper.FormatResourceString()", esta tarea tiene que registrar sus recursos durante la construcción o mediante la propiedad "TaskResources".
   en Microsoft.Build.Shared.ErrorUtilities.ThrowInvalidOperation(String resourceName, Object[] args)
   en Microsoft.Build.Shared.ErrorUtilities.VerifyThrowInvalidOperation(Boolean condition, String resourceName, Object arg0)
   en Microsoft.Build.Utilities.TaskLoggingHelper.FormatResourceString(String resourceName, Object[] args)
   en Microsoft.Build.Utilities.TaskLoggingHelper.LogErrorWithCodeFromResources(String messageResourceName, Object[] messageArgs)
   en Microsoft.CodeAnalysis.BuildTasks.CopyRefAssembly.Copy()
   en Microsoft.CodeAnalysis.BuildTasks.CopyRefAssembly.Execute()
   en Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
   en Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__26.MoveNext()  Sistema.Web  C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets  4521  


Si lo hago desde consola de comandos me retorna este error:

error MSB4126: La configuración de soluciones especificada "relise|Any CPU" no es válida. Especifique una configuración de soluciones válida con las propiedades Configuration y Platform (p. ej., MSBuild.exe Solution.sln /p:Configuration=Debug /p:Platform="Any CPU") o deje esas propiedades en blanco para usar la configuración de soluciones predeterminada.

Sabes a que puede ser debido.

Estado mirando por internet, pero no encuentro nada claro.

¡Muchas gracias de antemano!

Saludos!

Responder

José Manuel Alarcón - campusMVP.es
José Manuel Alarcón - campusMVP.es

Hola Rubén:

¿Pero esto te pasa al intentar hacerlo para un solo ejecutable (lo que habla el artículo) o te pasa en general?

La verdad es que no me ha pasado nunca nada similar, pero imagino que si te cargas los perfiles de publicación y los vuelves a crear desde cero debería irte bien. Para ello, puedes ir a la carpeta "properties" y eliminar de allí la subcarpeta "PublichProfiles". Luego en Visual Studio vete a "Publicar" y crea un nuevo perfil a ver si así te va.

Por otro lado en las propiedades del proyecto mira en "Build" qué tienes elegido en la plataforma de destino ("Platform Target"). Deberías tener normalmente "Any CPU" que es lo que te está dando problemas desde línea de comandos. Prueba a cambiarlo y poner "x64" o "x32" a ver si así te va.

Ya nos cuentas.

Saludos.

Responder

Rubén Vaquero Jiménez
Rubén Vaquero Jiménez

Hola José,

Revise todo lo que em indicas previamente, pero fue gracias a que me salto una notificación en la pantalla del antivirus pude ver que era.
Realmente no estaba haciendo nada mal el problema radicaba en que mi antivirus (uso el 360 full pero imagino que puede pasar con muchos por si quieres apuntarlo en posibles problemas) me estaba bloqueando la exportación de la carpeta Sistema.Web. Conseguí publicar la solución exportándolo en una carpeta y posteriormente Generando un sitio en IISS haciendo referencia a mi carpeta Relise.

Configurando previamente el usuario y pass correspondiente en mi SQL Server y las referencias que hay en main.js de mi proyecto Vue.js(Frontal) para que apunten a mi nuevo sitio, así como en mi appsettings.json de mi proyecto Sistema.Web indicando la ruta de conexión al servidor de BBDD y en mi JWT del mismo .json para que en vez de apuntar a local apunte a mi nuevo sitio y así conseguir acceso retornando un token válido para poder iniciar sesión.

Con esos pequeños cambios y luego en la parte de _Layout de mi proyecxto Net Core 5 ya que al recompilar una nueva solución de vue.js siempre crea los paquetes de .css y .js con un valor incremental. La aplicación empezó a funcionar de forma correcta en el IIS.

¿Sabes de algún hosting barato en el que pueda alojar la app en Net Core5, Vue.js (aunque esta parte no creo que influya al realizar yo la integración) y SQL server?

Muchísimas gracias por tu tutorial y sobre todo por tu contestación. Espero que estes muy bien tanto tu como tu familia.

Seguiré viendo más tutos ahora a ver si doy con la tecla de login a ver que le duele ahora jajaj, a no que esto ya está tmb :)

Un cordial saludo,
Rubén Vaquero Jiménez

Responder

José Manuel Alarcón - campusMVP.es
José Manuel Alarcón - campusMVP.es

Ah, estupendo. Unpopular opinion 🤷🏻‍♂️: yo es que recomiendo dejar el antivirus que trae Windows (que es bastante bueno) y dejar fuera los demás, que normalmente interfieren demasiado, dan problemas de todo tipo, cargan las máquinas.. y no te ofrecen una mejor seguridad.

En cuanto a lo del hosting, no te puedo hablar de primera mano porque hace años que no uso un hosting (utilizo o bien servidores propios virtualizados en la nube o bien Azure Web Apps: por ejemplo este blog está en una). Lo siento.

Saludos.

Responder

Hola José,

Como siempre agradecerte compartir tus conocimientos. he intentado realizar lo que me indicas con una aplicación en net Core con Vue.

Pero me sale el siguiente error
PS C:\Users\rubva\Desktop\Aplicaciones\AplicacionesGit\SistemaTasacionNetCore5VueJs\SistemaTasacionesCore5> dotnet publish -c relise -r win10-x64 -o C:\Relises
MSBuild version 17.3.1+2badb37d1 for .NET
C:\Users\rubva\Desktop\Aplicaciones\AplicacionesGit\SistemaTasacionNetCore5VueJs\SistemaTasacionesCore5\SistemaTasacionesCore5.sln.metaproj : error MSB4126: La configuración de soluciones especificada "relise|Any CPU" no es válida. Especifique una configuración de soluc
iones válida con las propiedades Configuration y Platform (p. ej., MSBuild.exe Solution.sln /p:Configuration=Debug /p:Platform="Any CPU") o deje esas propiedades en blanco para usar la configuración de soluciones predeterminada. [C:\Users\rubva\Desktop\Aplicaciones\Apli
cacionesGit\SistemaTasacionNetCore5VueJs\SistemaTasacionesCore5\SistemaTasacionesCore5.sln]

¿Sabes a que puede ser debido?


Para otra app que tengo en MVC5 .net se puede realizar este mismo proceso?


Responder

José Manuel Alarcón
José Manuel Alarcón

Hola Rubén:

Por lo que parece, del mensaje de error, has escrito mal "release", poniendo "relise" por error. Escríbelo bien y debería funcionar.

Saludos,

Responder

VladoDotNet
VladoDotNet

Cordial saludo!

Exelente tutorial!

Mostrar variantes es una estupenda alternativa pedagogica, algo que acostumbro en mis clases de la U.

Gracias.

PD. Un pequeño ajuste en el uso de algunos términos como 'tarda o pesa un montón'. 7/10 segundos o 65 MB son cifras insignificantes.

Lo que sucede es que la actual generación, y para todas las generaciones igual, posee grandes fortalezas como defectos.

La generación actual de mis estudiantes son ansiosos.
Todo lo quieren en cero (0) segundos y con menos de 5MB.
Cierto, el valor de la paciencia parece tender a la extinción.

Bendiciones en su proyecto de vida, ingeniero Alarcón.

César, Bogotá, Colombia

Responder

Agregar comentario

Los datos anteriores se utilizarán exclusivamente para permitirte hacer el comentario y, si lo seleccionas, notificarte de nuevos comentarios en este artículo, pero no se procesarán ni se utilizarán para ningún otro propósito. Lee nuestra política de privacidad.