usando ILMerge with.NET 4 bibliotecas


Dos problemas:

1) Ensamblaje Básico. NET No Incluido en el Ensamblaje Emergente

Estoy teniendo problemas para usar ILMerge en mi post-compilació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 objetivo se establece en". NET Framework 4". Utilizo el siguiente comando ILMerge para fusionar las DLL de cada proyecto 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 de en el directorio. NET 4 framework, recibo un error de "Referencia de ensamblado no permitida: Sistema" de ILMerge. Si dejo de especificar la ubicación del directorio MSTest, obtengo una " Referencia de ensamblado sin resolver no permitida: Microsoft. VisualStudio.Herramientas de calidad.UnitTestFramework " error.

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

La referencia primaria "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 superior "4.0.65535.65535" que la versión "4.0.0.0" en el marco de destino actual.

Si elimino la bandera /targetplatform:v4 e intento usar MyILMergedDLL.dll, obtengo el siguiente error:

El tipo Sistema.XML.Serialización.IXmlSerializable ' se define en un ensamblado al que no se hace referencia. Debe agregar una referencia al Sistema de ensamblaje.Xml, Version = 4.0.0.0, Culture=neutral, PublicKeyToken = b77a5c561934e089'.

No parece que deba hacer eso. Quien use mi MyILMergedDLL.dll API 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 Utiliza Fusionado Asamblea

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

Sistema.TypeLoadException:No se pudo cargar el sistema de tipo'.Func ' 2 'from assembly' MyILMergedDLL, Version = 1.0.1.1, Culture=neutral, PublicKeyToken=...'.

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

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

El constructor particular Row que lanza el TypeLoadException se define en una clase pública en MyILMergedDLL, y cuando uso este constructor al hacer referencia a los archivos DLL de proyecto individuales, funciona bien. Es solo cuando uso este constructor al hacer referencia a la DLL IL-merged que obtengo la excepción. No se que está pasando.

Aquí está ese constructor:

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

Y el base al que se refiere tiene este código:

foreach (string key in keys.Where(
    key => !string.IsNullOrEmpty(key)
))
{
    _dic.Add(key, string.Empty);
}
Author: starblue, 2010-06-03

6 answers

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


Addendum. Hay algo muy, muy mal en tu opción /lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319". Esto ha estado poniendo a muchos programadores en problemas últimamente, después de que.NET 4.5 fuera lanzado. Ese directorio es no el apropiado para los ensamblados de referencia.NET 4.0. Su contenido se sobrescribe con el ensamblados 4.5, ya no se puede usar 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. Normalmente bombardeando el atributo [Extension], a veces en la interfaz ICommand.

Estos tipos, y algunos otros, fueron trasladados de una asamblea a otra. El uso de los conjuntos de referencia correctos es un requisito duro como una roca. Usted debe usar:

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

Ajuste para que coincida con su máquina y objetivo en particular versión del framework.

 49
Author: Hans Passant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-06 09:17:07

Aquí está la "Cadena de compilación posterior" para Visual Studio 2010 SP1, utilizando.NET 4.0. Estoy construyendo una consola .exe con todos los sub -.archivos 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 la salida .el archivo exe termina.
  • Observe el directorio "ILMerge\". Copié la utilidad ILMerge en el directorio de mi solución (para poder distribuir el código fuente sin tener que preocuparme por documentar la instalación de ILMerge).

Consejos avanzados:

Si tiene problemas con que no funcione, agregue un "echo" antes del comando "Post Build". A continuación, abra la ventana "Output" en Visual Studio (View..Salida), 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

Update

Añadido esto a mi paso "Post Build", reemplaza a todos .exe + .archivos dll con un solo combinado .exe. También mantiene la depuración .archivo pdb intacto:

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
 21
Author: Contango,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-20 10:15:35
 2
Author: Contango,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-23 16:08:04

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 aquí

 2
Author: sebagomez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-26 14:38:08

Simplemente configure las referencias de PresentationCore y PresentationFramework para que tengan "Copy Local = True" en la ventana de propiedades de Visual Studio (después de seleccionar las referencias en el Explorador de soluciones). Resolverá el problema sin codificar la ruta del marco. 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 publiquen nuevas versiones de.NET/VS.

 1
Author: Tony Wall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-26 14:38:03

Para aquellos, que utilizan ILMerge de tareas comunitarias en.csproj:

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

Tenemos un parque mixto de agentes de construcción de CI, por lo que usamos la variable de entorno Program(ProgramFiles) para apuntar la ruta correcta (carpeta drive + x86/x64), como lo recomendó el Equipo de MSBuild.

 0
Author: ursa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-12 16:48:14