maximo - ¿Se puede comprimir una aplicación de Windows.NET en un solo.exe?
comprimir y descomprimir archivos (12)
Como se ha dicho, puedes usar ILMerge .
Sin embargo, puede ser más fácil si usa el protector Phoenix gratuito , que también protege su código.
No estoy muy familiarizado con las aplicaciones de escritorio .NET (usando Visual Studio 2005 ). ¿Es posible ejecutar toda la aplicación desde un solo archivo .exe?
Estoy usando .netshrink , y hace exactamente lo que necesitas. Encapsula los conjuntos principales y extra (archivos DLL) en una imagen ejecutable.
Ya lo he usado durante un año, y no volveré a ILMerge (siempre falla en algún momento ...).
Hay una herramienta de terceros llamada .NET Reactor que puede hacer esto por usted. No he usado la herramienta y no estoy seguro de qué tan bien funcione.
He usado el .NETZ .NET packer ejecutable de código abierto para empacar los archivos EXE y DLL en un solo archivo EXE. Aquí hay un ejemplo de línea de comando sobre cómo empacar los archivos DLL en un archivo:
netz -s application.exe foo.dll bar.dll
Hoy, en 2015, puedes usar Costura.Fody para esto. Usarlo equivale a agregar el paquete NuGet a su proyecto y volver a compilar. No estoy seguro si funciona con Visual Studio 2005 como en la pregunta, pero tampoco es el año 2008. Lo he usado en algunos de mis proyectos y funcionó muy bien.
Fody es un Code Weaver de propósito general que es de código abierto y gratuito. La idea básica de que permite el procesamiento posterior del código .NET compilado para mejorarlo con características. Por ejemplo, el registro se puede agregar a cada llamada de método, etc. En nuestro caso, está empaquetando los archivos DLL dependientes en los recursos de ensamblado, de modo que puedan cargarse durante el tiempo de ejecución del programa como si fueran dependencias independientes.
No debe dividirlo en varios conjuntos (que generalmente son proyectos dentro de una solución de Visual Studio). El .NET Framework es obligatorio de todos modos, no hay forma, y esa es la forma correcta, de incrustarlo.
Puede probar la utilidad NBox .
1.
Sí, puedes crear un solo archivo EXE. Dos buenos artículos son:
Sí, puedes usar la herramienta ILMerge .
ILMerge puede combinar ensamblajes en un solo ensamble siempre que el ensamble solo tenga código administrado. Puede usar la aplicación de línea de comandos, o agregar referencia al archivo EXE y fusionar programáticamente. Para una versión de GUI, hay Eazfuscator , y también .NETZ , ambos gratuitos. Las aplicaciones pagas incluyen BoxedApp y SmartAssembly .
Si tiene que combinar ensamblajes con código no administrado, sugeriría SmartAssembly . Nunca tuve problemas con SmartAssembly , pero con todos los demás. Aquí, puede incorporar las dependencias requeridas como recursos a su archivo EXE principal.
Puede hacer todo esto de forma manual, sin necesidad de preocuparse si se administra un ensamblado o en modo mixto mediante la incrustación del archivo DLL en sus recursos y luego confiar en Assembly ResolveHandler
AppDomain. Esta es una solución integral adoptando el peor de los casos, es decir, ensamblados con código no administrado.
class Program
{
[STAThread]
static void Main()
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
string assemblyName = new AssemblyName(args.Name).Name;
if (assemblyName.EndsWith(".resources"))
return null;
string dllName = assemblyName + ".dll";
string dllFullPath = Path.Combine(GetMyApplicationSpecificPath(), dllName);
using (Stream s = Assembly.GetEntryAssembly().GetManifestResourceStream(typeof(Program).Namespace + ".Resources." + dllName))
{
byte[] data = new byte[stream.Length];
s.Read(data, 0, data.Length);
// Or just byte[] data = new BinaryReader(s).ReadBytes((int)s.Length);
File.WriteAllBytes(dllFullPath, data);
}
return Assembly.LoadFrom(dllFullPath);
};
}
}
Donde el Program
es el nombre de la clase. La clave aquí es escribir los bytes en un archivo y cargar desde su ubicación. Para evitar un problema de huevo y gallina, debe asegurarse de declarar el controlador antes de acceder al ensamblaje y de que no tiene acceso a los miembros del ensamblaje (o crear una instancia de todo lo que tenga que ver con el ensamblaje) dentro de la carga (resolución de ensamblaje) parte. También asegúrese de que GetMyApplicationSpecificPath()
no sea un directorio temporal, ya que los archivos temporales pueden ser borrados por otros programas o usted mismo (no es que se borre mientras su programa está accediendo al archivo DLL, pero al menos es una molestia . AppData es una buena ubicación). También tenga en cuenta que debe escribir los bytes cada vez; no puede cargar desde la ubicación solo porque el archivo DLL ya reside allí.
Para los archivos DLL administrados, no necesita escribir bytes, sino cargar directamente desde la ubicación del archivo DLL, o simplemente leer los bytes y cargar el ensamblaje desde la memoria. Me gusta esto o algo así:
using (Stream s = Assembly.GetEntryAssembly().GetManifestResourceStream(typeof(Program).Namespace + ".Resources." + dllName))
{
byte[] data = new byte[stream.Length];
s.Read(data, 0, data.Length);
return Assembly.Load(data);
}
// Or just
return Assembly.LoadFrom(dllFullPath); // If location is known.
Si el ensamblado no está completamente administrado, puede ver este enlace o this sobre cómo cargar dichos archivos DLL.
Jeffrey Richter escribió en su extracto del libro que se puede registrar un método de devolución de llamada con el evento ResolveAssembly del dominio de la aplicación para permitir que CLR encuentre ensamblados de terceros y archivos DLL durante la inicialización del programa:
AppDomain.CurrentDomain.AssemblyResolve += (sender,
args) => {
String resourceName = "AssemblyLoadingAndReflection." +
new AssemblyName(args.Name).Name + ".dll";
using (var stream =
Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)){
Byte[] assemblyData = new Byte[stream.Length];
stream.Read(assemblyData, 0, assemblyData.Length);
return Assembly.Load(assemblyData);
}
};
Descargo de responsabilidad : Yo no he usado esto yo mismo. Por lo que yo entiendo, el cliente aún necesita tener .NET Framework instalado.
Sí. En .NET puede tener toda su aplicación encapsulada como un único archivo EXE. Solo asegúrese de que su solución solo tenga un proyecto de aplicación de Windows (y ningún otro proyecto a excepción de las configuraciones).
El archivo EXE creado por su proyecto .NET no será un archivo ejecutable independiente, pero la única dependencia que tendrá será el tiempo de ejecución .NET (a menos que agregue referencias a otros ensamblados de DLL). Si usa .NET 2.0 (que recomiendo), el tiempo de ejecución viene preinstalado en PC más nuevas y es muy fácil y rápido de instalar en máquinas más antiguas (el instalador cuesta unos 23 MB).
Si su aplicación necesita hacer referencia a otros ensambles (como un DLL de acceso a datos o un proyecto DLL de biblioteca .NET), puede usar una de las herramientas mencionadas aquí para combinar su EXE y todas las DLL referenciadas en un único archivo EXE. . Sin embargo, la práctica convencional dictaría simplemente implementar el archivo EXE junto con las DLL dependientes como archivos separados . En .NET, la implementación de archivos DLL dependientes es bastante simple: simplemente colóquelos en la misma carpeta que el archivo EXE en el equipo cliente, y listo.
Es una buena práctica desplegar su aplicación (ya sea un archivo o muchos) como un instalador de un solo archivo (ya sea un setup.EXE o setup.MSI). .NET viene con plantillas de proyectos de implementación que pueden crear instaladores para usted con bastante facilidad.
Un poco fuera de tema: podría usar NGEN para compilar su aplicación .NET como un EXE nativo, pero aún dependería del tiempo de ejecución de .NET. La ventaja de la compilación nativa es que algunas cosas se pueden compilar previamente, pero nunca he visto una situación en la que este pequeño aumento en el rendimiento valga la pena.