2008-09-24 10 views

Respuesta

28

Sí, puede usar la herramienta ILMerge.

+0

Hasta ahora me ha funcionado, incluso para .NET 4.0, usando la sugerencia dada en la página del proyecto. – Marcel

5

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.

+1

Lo usamos, funciona bien. – RickL

+0

Aún necesita el .net Framework. 'Native' solo describe el enfoque de protección. –

+0

Gracias por esa información, he actualizado la respuesta para reflejar esto. –

0

No debe dividirlo en varios ensamblados (que normalmente 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.

5

He utilizado el .NETZ .NET packer ejecutable de código abierto para empacar archivos EXE y DLL en un solo archivo EXE. Aquí es un ejemplo de línea de comandos de cómo empaquetar los archivos DLL en un archivo:

netz -s application.exe foo.dll bar.dll 
+1

Hola, he usado netz. Pero no funciona con dependencias no administradas. – mrid

+0

también estoy usando un servicio web que no es compatible. .NetZ es muy bueno con demasiadas opciones, pero descontinuado. – Zolfaghari

8

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 de .NET (a menos que agregue referencias a otros ensamblados 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 una DLL de acceso a datos o una DLL de biblioteca .NET), puede usar una de las herramientas referenciadas aquí para combinar su EXE y todas las DLL mencionadas en un solo 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 varias) como un instalador de un solo archivo (ya sea 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 utilizar NGEN para compilar su aplicación .NET como un EXE nativo, pero seguiría dependiendo 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.

1

Usted puede probar la utilidad NBox.

0

ILMerge puede combinar conjuntos a un único conjunto proporcionan el conjunto ha código sólo 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 de pago incluyen BoxedApp y SmartAssembly.

Si tiene que combinar ensamblajes con código no administrado, sugeriría SmartAssembly. Nunca tuve hipo 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 manualmente, 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 el conjunto ResolveHandler de 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 Program es el nombre de 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 manipulador antes de acceder al ensamblaje y de no tener 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 asegurarse de que GetMyApplicationSpecificPath() no sea un directorio temporal, ya que los archivos temporales pueden ser borrados por otros programas o por usted mismo (no es que se eliminen mientras su programa está accediendo al archivo DLL, pero al menos es una molestia). 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. Como esto más o menos:

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 conjunto es completamente administrado, se puede ver this link o this en cuanto a cómo cargar estos archivos DLL.

1

Estoy usando .netshrink yo mismo, y hace exactamente lo que necesita. Encapsula los conjuntos principales y extra (archivos DLL) en una imagen ejecutable.

Hace un año que lo uso y no volveré a ILMerge (siempre falla en algún momento ...).

.netshrink main window from the product's page

+1

No es gratis ... –

1

Jeffrey Richter escribió en su book excerpt que un método de devolución de llamada con el evento application domain’s ResolveAssembly se puede registrar para que el CLR encontrar asambleas de terceros y archivos DLL durante el programa de inicialización:

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); 
     } 
    }; 

Exención de responsabilidad: No he usado esto por mi cuenta. Por lo que yo entiendo, el cliente aún necesita tener .NET Framework instalado.

+0

Este es aparentemente el método utilizado por Costura.Fody que se describe en la otra respuesta: https://stackoverflow.com/a/32556235/3195477 – DaveInCaz

8

Hoy, en 2015, puede usar Costura.Fody para esto. Usarlo equivale a agregar el paquete NuGet a su proyecto y volver a compilar. No estoy seguro de 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 propósito general Code Weaver que es de fuente abierta y gratuita. 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.

+2

Esa es una respuesta correcta. Acabo de probar ot con VS 2015 y la aplicación WPF. ¡Gracias! –

+2

Me pareció excelente para mi proyecto que use Roslyn. Lo instalé a través del administrador de Nuget, y luego ... viola! Simplemente funciona bien fuera de la caja. OP: por favor acepte esta respuesta. – lwchkg

+0

Excelente respuesta, literalmente solo instale el paquete Nuget y reconstruya. Fácil. – saarrrr

Cuestiones relacionadas