tutorial gui example .net dll assemblies c#-4.0 ilmerge

gui - utilizando ILMerge con bibliotecas.NET 4



ilmerge tutorial (6)

Aquí está el "Post Build String" para Visual Studio 2010 SP1, usando .NET 4.0. Estoy construyendo un .exe de consola con todos los archivos sub-.dll incluidos en él.

"$(SolutionDir)ILMerge/ILMerge.exe" /out:"$(SolutionDir)/deploy/$(TargetFileName)" "$(TargetDir)$(TargetFileName)" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:/Windows/Microsoft.NET/Framework64/v4.0.30319 /wildcards

Consejos básicos:

  • Observe el directorio "/ deploy /": aquí es donde termina el archivo .exe de salida.
  • Observe el directorio "ILMerge /". Copié la utilidad ILMerge en mi directorio de solución (para poder distribuir la fuente sin tener que preocuparme de documentar la instalación de ILMerge).

Consejos avanzados:

Si tiene problemas y no funciona, agregue un "eco" antes del comando "Publicar compilación". A continuación, abra la ventana "Salida" en Visual Studio (View..Output) y compruebe el comando exacto que Visual Studio realmente generó. En mi caso particular, el comando exacto fue:

"T:/PhiEngine/CSharp/ILMerge/ILMerge.exe" /out:"T:/PhiEngine/CSharp/Server Side/deploy/NfServiceDataHod.History.exe" "T:/PhiEngine/CSharp/Server Side/NfServiceDataHod/bin/Debug/NfServiceDataHod.History.exe" "T:/PhiEngine/CSharp/Server Side/NfServiceDataHod/bin/Debug/*.dll" /target:exe /targetplatform:v4,C:/Windows/Microsoft.NET/Framework64/v4.0.30319 /wildcards

Actualizar

Agregué esto a mi paso "Post Build", reemplaza todos los archivos .exe + .dll con un solo .exe combinado. También mantiene intacto el archivo .pdb de depuración:

rem Create a single .exe that combines the root .exe and all subassemblies. "$(SolutionDir)ILMerge/ILMerge.exe" /out:"$(TargetDir)$(TargetName).all.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:/Windows/Microsoft.NET/Framework64/v4.0.30319 /wildcards rem Remove all subassemblies. del *.dll rem Remove all .pdb files (except the new, combined pdb we just created). ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).all.pdb.temp" del *.pdb ren "$(TargetDir)$(TargetName).all.pdb.temp" "$(TargetName).all.pdb" rem Delete the original, non-combined .exe. del "$(TargetDir)$(TargetName).exe" rem Rename the combined .exe and .pdb to the original name we started with. ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).pdb" ren "$(TargetDir)$(TargetName).all.exe" "$(TargetName).exe" exit 0

Dos problemas:

1) Ensamblaje .NET básico no incluido en ensamblado ILMerged

Tengo problemas para usar ILMerge en mi postcompilación después de actualizar de .NET 3.5 / Visual Studio 2008 a .NET 4 / Visual Studio 2010. Tengo una solución con varios proyectos cuyo marco de destino está configurado en ".NET Framework 4" . Uso el siguiente comando ILMerge para combinar las DLL de proyecto individuales en una sola DLL:

if not $(ConfigurationName) == Debug if exist "C:/Program Files (x86)/Microsoft/ILMerge/ILMerge.exe" "C:/Program Files (x86)/Microsoft/ILMerge/ILMerge.exe" /lib:"C:/Windows/Microsoft.NET/Framework64/v4.0.30319" /lib:"C:/Program Files (x86)/Microsoft Visual Studio 10.0/Common7/IDE/PublicAssemblies" /keyfile:"$(SolutionDir)$(SolutionName).snk" /targetplatform:v4 /out:"$(SolutionDir)bin/development/$(SolutionName).dll" "$(SolutionDir)Connection/$(OutDir)Connection.dll" ...other project DLLs... /xmldocs

Si dejo de especificar la ubicación del directorio .NET 4 framework, aparece un error de "Referencia de ensamblaje no resuelto no permitido: Sistema" de ILMerge. Si dejo de especificar la ubicación del directorio MSTest, aparece el error "Referencia de ensamblaje no resuelto no permitido: Microsoft.VisualStudio.QualityTools.UnitTestFramework".

El comando ILMerge anterior funciona y produce una DLL. Sin embargo, cuando hago referencia a esa DLL en otro proyecto .NET 4 C # y trato de usar código dentro de ella, recibo la siguiente advertencia:

La referencia principal "MyILMergedDLL" no se pudo resolver porque tiene una dependencia indirecta del ensamblado de .NET Framework "mscorlib, Version = 4.0, Culture = neutral, PublicKeyToken = b77a5c561934e089" que tiene una versión más alta "4.0.65535.65535" que la versión "4.0.0.0" en el marco de destino actual.

Si, a continuación, /targetplatform:v4 el /targetplatform:v4 e intento utilizar MyILMergedDLL.dll, aparece el siguiente error:

El tipo ''System.Xml.Serialization.IXmlSerializable'' se define en un conjunto al que no se hace referencia. Debe agregar una referencia al ensamblado ''System.Xml, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089''.

No parece que deba hacer eso. Quien use mi API MyILMergedDLL.dll no debería tener que agregar referencias a las bibliotecas a las que hace referencia. ¿Cómo puedo evitar esto?

2) TypeLoadException solo cuando se usa ensamblado combinado

Editar: más allá de esto, incluso si agrego una referencia a System.Xml en el proyecto del consumidor que usa MyILMergedDLL.dll, haciendo uso de algún código en MyILMergedDLL.dll da esta excepción:

System.TypeLoadException: No se pudo cargar el tipo ''System.Func`2'' desde el ensamblado ''MyILMergedDLL, Version = 1.0.1.1, Culture = neutral, PublicKeyToken = ...''.

Este es el código en mi proyecto de consumo; la línea que causó la TypeLoadException es la segunda:

var keys = new[] {"a", "b", "c"}; var row = new Row(keys);

El constructor de Row particular que arroja la TypeLoadException se define en una clase pública en MyILMergedDLL , y cuando utilizo este constructor al hacer referencia a las DLL de proyecto individuales, funciona bien. Solo cuando uso este constructor al hacer referencia a la DLL fusionada con IL recibo la excepción. No sé lo que está pasando.

Aquí está ese constructor:

public Row(IEnumerable<string> keys) : base(keys) { }

Y la base a la que se refiere tiene este código:

foreach (string key in keys.Where( key => !string.IsNullOrEmpty(key) )) { _dic.Add(key, string.Empty); }


Hubo un lanzamiento muy reciente para resolver problemas x64. Póngase en contacto con Mike Barnett directamente si todavía tiene problemas (mbarnett en microsoft dot com)

Apéndice. Hay algo muy, muy incorrecto sobre su opción /lib:"C:/Windows/Microsoft.NET/Framework64/v4.0.30319" . Esto ha estado teniendo muchos programadores en problemas últimamente, después de que se lanzara .NET 4.5. Ese directorio no es el adecuado para los ensamblados de referencia de .NET 4.0. Su contenido se sobrescribe con los ensamblados 4.5, ya no puede usarlo para apuntar a una instalación de .NET 4.0. El error de tiempo de ejecución que obtienes es muy incómodo, el programa ya no puede encontrar ciertos tipos. Suele bombardear el atributo [Extensión], a veces en la interfaz ICommand.

Estos tipos, y algunos otros, se movieron de un ensamblaje a otro. Usar los ensambles de referencia correctos es un requisito difícil. Debes usar:

/lib:"C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETFramework/v4.0"

Ajuste para que coincida con su máquina particular y la versión del marco de destino.



Para aquellos que usan ILMerge de las tareas de la comunidad en .csproj:

<ILMerge InputAssemblies="@(MergeAssemblies)" ... TargetPlatformVersion="v4" TargetPlatformDirectory="$(ProgramFiles)/Reference Assemblies/Microsoft/Framework/.NETFramework/v4.0" />

Hemos mezclado el parque de agentes de compilación de CI, por lo que usamos la variable de entorno $ (ProgramFiles) para señalar la ruta correcta (carpeta drive + x86 / x64), como lo recomendó MSBuild Team .


Simplemente configure las referencias de PresentationCore y PresentationFramework para que tengan "Copiar local = Verdadero" en la ventana de propiedades de Visual Studio (después de seleccionar las referencias en el Explorador de soluciones). Solucionará el problema sin codificar el camino del framework. Prefiero esta solución porque la ruta es diferente dependiendo de si el desarrollador / servidor de compilación es de 64 bits o 32 bits e inevitablemente cambiará a medida que se lanzan nuevas versiones de .NET / VS.


También puede agregar un archivo de configuración con lo siguiente:

<?xml version ="1.0"?> <configuration> <startup useLegacyV2RuntimeActivationPolicy="true"> <requiredRuntime safemode="true" imageVersion="v4.0.30319" version="v4.0.30319"/> </startup> </configuration>

Tomado de here