c# - mvc - ¿Hay alguna manera de hacer que una aplicación de consola se ejecute utilizando un solo archivo en.NET Core?
asp net core mvc (3)
En .NET Framework, puede crear un solo archivo .EXE
que se ejecute desde la línea de comandos sin tener ningún archivo de configuración adicional (y si usa ILMerge, puede colocar todas las referencias .DLL
en el ensamblado 1 .EXE
).
Estoy probando el uso de .NET Core para lograr lo mismo, pero hasta ahora sin éxito. Incluso la aplicación Hello World
más simple sin dependencias requiere que haya un archivo llamado <MyApp>.runtimeconfig.json
para ejecutarse con dotnet.exe
.
dotnet F:/temp/MyApp.dll
El contenido de <MyApp>.runtimeconfig.json
es el siguiente:
{
"runtimeOptions": {
"framework": {
"name": "Microsoft.NETCore.App",
"version": "1.1.1"
}
}
}
Sin este archivo de configuración en la misma carpeta que el .DLL
, obtengo el siguiente error:
A fatal error was encountered. The library ''hostpolicy.dll'' required to
execute the application was not found in ''F:/temp''.
Mi pregunta es: ¿hay alguna forma de cambiar la aplicación para que no requiera que este archivo de configuración esté presente, de modo que los valores predeterminados de esta información se compilen dentro de .DLL
pero se puedan invalidar agregando el archivo de configuración?
NOTA: También quiero asegurarme de que "simplemente funciona" independientemente de la plataforma en la que esté instalada, siempre que la plataforma tenga la versión correcta de .NET Core.
Fondo
Estoy tratando de obtener una experiencia de usuario fluida para ejecutar algunas utilidades que a veces son útiles, pero que rara vez son necesarias. Dado que no parece ser posible utilizar el mismo .DLL
que se hace referencia desde una aplicación cliente como una aplicación de consola, lo mejor sería tener un solo archivo que se pueda descargar y ejecutar sin ninguna dependencia.
Por ejemplo, en Java, simplemente puede descargar un archivo .jar
en cualquier plataforma compatible y ejecutar:
java <package>.jar <namespace>.SomeClass [args]
y "simplemente funcionará" sin ningún archivo adicional. ¿Cómo puedo obtener una experiencia de usuario similar con .NET Core?
En pocas palabras, quiero intentar evitar el paso adicional de "descomprimir primero un directorio" ...
Es posible en .NET Core 3.0
Digo que sí, porque la vista previa actual (5) permite su uso y (por lo que puedo decir por mi experiencia) funciona bien.
La función se habilita mediante el uso de la siguiente propiedad en su archivo de proyecto (.csproj):
<PropertyGroup>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
También hay otras opciones, como empaquetar el pdb en el paquete o dejar ciertos archivos fuera.
La documentación no es fácil de encontrar (ya que todavía es una vista previa), pero hay un documento extenso desde la etapa de la propuesta, que especifica su uso: https://github.com/dotnet/designs/blob/master/accepted/single-file/design.md
Es cierto que simplemente funciona :
Combine esta técnica con el flujo de trabajo de la Distribución Autónoma , puede obtener una verdadera experiencia "simplemente funciona" para su usuario, ni siquiera tienen que instalar .NET Core runtime para que se ejecute su aplicación.
Actualmente estoy implementando aplicaciones para mis clientes como archivos .exe individuales.
Lea más sobre eso aquí: https://docs.microsoft.com/en-us/dotnet/core/deploying/#self-contained-deployments-scd
Probado con .NET Core 2.2 en una aplicación de consola :
- Consulte Microsoft.DotNet.ILCompiler paquete Microsoft.DotNet.ILCompiler en su proyecto de salida. Deberá agregar el repositorio de paquetes MyGet en la configuración de Visual Studio. *
- Publique el proyecto a través de la línea de comandos, publique en dotnet C: / src / App / App.csproj -c release -r win-x64 -o output-win-x64 . Si no hay un componente "Desarrollo de escritorio para C ++" instalado, hágalo en Visual Studio Installer, o el comando fallará.
- Vaya a la carpeta de salida (por ejemplo, "C: / src / App / output-win-x64") y tome la imagen nativa (archivo .exe).
En Windows, produjo un archivo .exe completamente funcional de 5Mb (en comparación con la publicación original autocontenida con un tamaño de carpeta de ~ 60Mb). En macOS, aunque el ILComplier produjo resultados sin ningún error, la aplicación se bloqueó con una revisión no controlada (en la línea con la expresión LINQ).
* Vaya a "Herramientas -> Opciones -> Administrador de paquetes -> Orígenes de paquetes" y agregue una nueva fuente en https://dotnet.myget.org/F/dotnet-core/api/v3/index.json
Actualización 2018: .NET Core 3.0 apunta a habilitar un nuevo escenario: empaquetar el tiempo de ejecución de .NET Core y todas las dependencias de la aplicación en un solo ejecutable.
En este momento, no hay métodos a prueba de fallas para crear un solo archivo ejecutable. Dado que hay muchos archivos dll de reenvío de tipo involucrados, incluso ILMerge y otras herramientas similares podrían no producir resultados correctos (aunque esto podría mejorar, el problema es que esos escenarios no han sido sometidos a pruebas exhaustivas, especialmente en aplicaciones de producción)
Actualmente hay dos formas de implementar una aplicación .NET Core:
- Como una "aplicación portátil" / "aplicación dependiente del marco" , se requiere un ejecutable
dotnet
y un marco instalado en la máquina de destino. Aquí, elXYZ.runtimeconfig.json
se utiliza para determinar la versión del marco a utilizar y también especifica los parámetros de tiempo de ejecución. Este modelo de implementación permite ejecutar el mismo código en varias plataformas (windows, linux, mac) - Como una "aplicación independiente" : aquí se incluye todo el tiempo de ejecución en la salida publicada y se genera un archivo ejecutable (por ejemplo,
yourapp.exe
). Esta salida es específica de una plataforma (establecida a través de un identificador de tiempo de ejecución) y solo se puede ejecutar en el sistema operativo de destino. Sin embargo, el ejecutable producido es solo un pequeño shim que inicia el tiempo de ejecución y carga el archivo dll principal de la aplicación. Esto también permite queXYZ.runtimeconfig.json
establezca propiedades de tiempo de ejecución adicionales como la configuración de recolección de basura (piense en ello como un "nuevo" archivoapp.config
)
En el futuro, el tiempo de ejecución CoreRT , que todavía está en desarrollo al momento de escribir, apunta a permitir la creación de un único archivo ejecutable nativo precompilado que sea específico para un tiempo de ejecución y no requiera ningún otro archivo.