Pergunta

Você usa ILMerge?Você usa o ILMerge para mesclar vários assemblies para facilitar a implantação de DLLs?Você encontrou problemas com implantação/versionamento em produção após ILMerging assemblies juntos?

Estou procurando alguns conselhos sobre o uso do ILMerge para reduzir o atrito na implantação, se isso for possível.

Foi útil?

Solução

Eu uso o ILMerge para quase todos os meus diferentes aplicativos.Eu o integrei diretamente no processo de criação da versão, então o que acabo é com um exe por aplicativo, sem DLLs extras.

Você não pode ILMerge nenhum assemblie C++ que possua código nativo.Você também não pode ILMerge nenhum assemblie que contenha XAML para WPF (pelo menos não tive sucesso com isso).Ele reclama em tempo de execução que os recursos não podem ser localizados.

Eu escrevi um executável wrapper para o ILMerge, onde passo o nome do exe de inicialização do projeto que desejo mesclar e um nome do exe de saída, e então ele reflete os assemblies dependentes e chama o ILMerge com os parâmetros de linha de comando apropriados.É muito mais fácil agora que quando adiciono novos assemblies ao projeto, não preciso me lembrar de atualizar o script de construção.

Outras dicas

Introdução

Esta postagem mostra como substituir todos .exe + .dll files com um único combined .exe.Ele também mantém a depuração .pdb arquivo intacto.

Para aplicativos de console

Aqui está o básico Post Build String para Visual Studio 2010 SP1, usando .NET 4.0.Estou construindo um console .exe com todos os arquivos sub-.dll incluídos nele.

"$(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

Dicas básicas

  • A saída é um arquivo "AssemblyName.all.exe" que combina todas as sub-dlls em um .exe.
  • Observe o ILMerge\ diretório.Você precisa copiar o utilitário ILMerge para o diretório da solução (para poder distribuir a fonte sem se preocupar em documentar a instalação do ILMerge) ou alterar este caminho para apontar para onde o ILMerge.exe reside.

Dicas avançadas

Se você tiver problemas com ele não funcionando, ligue Output, e selecione Show output from: Build.Verifique o comando exato que o Visual Studio realmente gerou e verifique se há erros.

Exemplo de script de construção

Este script substitui todos .exe + .dll files com um único combined .exe.Ele também mantém o arquivo .pdb de depuração intacto.

Para usar, cole isso em seu Post Build passo, sob o Build Events guia em um projeto C# e certifique-se de ajustar o caminho na primeira linha para apontar para ILMerge.exe:

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 project name we started with.
ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).pdb"
ren "$(TargetDir)$(TargetName).all.exe" "$(TargetName).exe"
exit 0

Usamos ILMerge nos blocos de aplicativos da Microsoft - em vez de 12 arquivos DLL separados, temos um único arquivo que podemos carregar em nossas áreas de cliente, além da estrutura do sistema de arquivos ser muito mais organizada.

Depois de mesclar os arquivos, tive que editar a lista de projetos do Visual Studio, remover os 12 conjuntos separados e adicionar o arquivo único como referência, caso contrário ele reclamaria que não conseguiu encontrar o assembly específico.Não tenho muita certeza de como isso funcionaria na pós-implantação, mas pode valer a pena tentar.

Eu sei que esta é uma questão antiga, mas não usamos apenas o ILMerge para reduzir o número de dependências, mas também para internalizar as dependências "internas" (por exemplo, automapper, restsharp, etc) que são usadas pelo utilitário.Isso significa que eles são completamente abstraídos e o projeto que usa o utilitário mesclado não precisa saber sobre eles.Isso novamente reduz as referências necessárias no projeto e permite usar/atualizar sua própria versão da mesma biblioteca externa, se necessário.

Usamos ILMerge em alguns projetos.O Fábrica de software de serviços web, por exemplo, produz algo como 8 assemblies como saída.Mesclamos todas essas DLLs em uma única DLL para que o host de serviço tenha apenas que fazer referência a uma DLL.

Isso torna a vida um pouco mais fácil, mas também não é grande coisa.

Tivemos o mesmo problema ao combinar dependências do WPF....O ILMerge não parece lidar com isso.Costura.Fody funcionou perfeitamente para nós e levou cerca de 5 minutos para começar...uma experiência muito boa.

Basta instalar com Nuget (selecionando o projeto padrão correto no Package Manager Console).Ele se apresenta no projeto alvo e as configurações padrão funcionaram imediatamente para nós.

Ele mescla todas as DLLs marcadas como "Copy Local" = true e produz um .EXE mesclado (junto com a saída padrão), que é bem compactado em tamanho (muito menor que o tamanho total da saída).

A licença é MIT para que você possa modificar/distribuir conforme necessário.

https://github.com/Fody/Costura/

Observe que para programas GUI do Windows (por exemplo, WinForms), você desejará usar o /target:vinho trocar.
O alvo:exe switch cria um mesclado console aplicativo.

Tivemos problemas ao mesclar DLLs que possuem recursos no mesmo namespace.No processo de fusão, um dos namespaces de recursos foi renomeado e, portanto, os recursos não puderam ser localizados.Talvez estejamos apenas fazendo algo errado, ainda investigando o problema.

Acabamos de começar a usar o ILMerge em nossas soluções que são redistribuídas e usadas em nossos outros projetos e até agora tudo bem.Tudo parece funcionar bem.Até ofuscamos diretamente o assembly empacotado.

Estamos pensando em fazer o mesmo com os assemblies da MS Enterprise Library.

O único problema real que vejo é o controle de versão de assemblies individuais do pacote.

Recentemente, tive um problema em que havia mesclado o assembly no assembly. Eu tinha algumas classes que estavam sendo chamadas via reflexão no CMS de código aberto Umbraco.

As informações para fazer a chamada via reflexão foram retiradas da tabela db que possuía nome do assembly e namespace da classe que implementou e interface.O problema era que a chamada de reflexão falharia quando a dll fosse mesclada, no entanto, se a dll fosse separada, tudo funcionaria bem.Acho que o problema pode ser semelhante ao que o longeasy está enfrentando.

Estou apenas começando a usar o ILMerge como parte da minha construção de CI para combinar muitos contratos WCF refinados em uma única biblioteca.Funciona muito bem, no entanto, a nova biblioteca mesclada não pode coexistir facilmente com suas bibliotecas de componentes ou com outras bibliotecas que dependem dessas bibliotecas de componentes.

Se, em um novo projeto, você fizer referência à biblioteca ILMerged e também a uma biblioteca legada que depende de uma das entradas que você forneceu ao ILMerge, descobrirá que não pode passar nenhum tipo da biblioteca ILMerged para qualquer método em a biblioteca herdada sem fazer algum tipo de mapeamento de tipo (por exemploautomapper ou mapeamento manual).Isso ocorre porque, depois que tudo estiver compilado, os tipos serão efetivamente qualificados com um nome de assembly.

Os nomes também irão colidir, mas você pode corrigir isso usando alias externo.

Meu conselho seria evitar incluir em seu assembly mesclado qualquer biblioteca disponível publicamente que seu assembly mesclado exponha (por exemplo,por meio de um tipo de retorno, parâmetro de método/construtor, campo, propriedade, genérico...), a menos que você tenha certeza de que o usuário do seu assembly mesclado não depende e nunca dependerá da versão independente da mesma biblioteca.

Parece-me que a prática recomendada nº 1 do ILMerge é não usar o ILMerge.Em vez disso, use SmartAssembly.Uma razão para isso é que a prática recomendada nº 2 do ILMerge é sempre executar o PEVerify depois de fazer um ILMerge, porque o ILMerge não garante que mesclará corretamente os assemblies em um executável válido.

Outras desvantagens do ILMerge:

  • ao mesclar, ele remove os comentários XML (se eu me importasse com isso, usaria uma ferramenta de ofuscação)
  • ele não lida corretamente com a criação de um arquivo .pdb correspondente

Outra ferramenta que merece atenção é o Mono.Cecil e a ferramenta Mono.Linker [2].

[2]:http://www.mono-project.com/Linker

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top