André Alves de Lima

Talking about Software Development and more…

Juntando executável e dlls em um arquivo só com o ILMerge

Você já desenvolveu um aplicativo que possui referências a diversas bibliotecas? Caso positivo, você sabe a dor de cabeça que enfrentamos na hora de distribuirmos esse tipo de aplicação. Basta esquecer uma simples dll e pronto: nossa aplicação não funcionará corretamente.

O que talvez você não saiba é que nós conseguimos mesclar executável e dlls em um arquivo só através da ferramenta chamada ILMerge. O resultado será um único executável (ou dll), tornando o processo de deployment muito mais fácil.

No artigo de hoje, confira como utilizar o ILMerge via linha de comando e conheça também o ILMergeGui, uma interface visual que interage com o ILMerge e facilita muito a nossa vida quando precisamos mesclar assemblies.

Criando um projeto de exemplo

Para entendermos como juntar vários assemblies em um único executável ou dll, vamos criar um exemplo extremamente simples. Esse exemplo será formado por um projeto “Console Application” (.exe) e dois projetos “Class Library” (.dll). Darei o nome de “ExemploILMerge” para a solução que será criada com a “Console Application“. Dentro dessa solution, vamos adicionar outros dois projetos do tipo “Class Library“, dando o nome de “Biblioteca1” e “Biblioteca2” respectivamente. A estrutura da solução deve ficar parecida com a imagem abaixo:

Dentro da “Class1” da “Biblioteca1“, vamos adicionar um método estático (chamado “Metodo“) que retornará uma string contendo “Biblioteca1.Class1.Metodo“:

// C#
namespace Biblioteca1
{
    public class Class1
    {
        public static string Metodo()
        {
            return "Biblioteca1.Class1.Metodo";
        }
    }
}
' VB.NET
Public Class Class1
    Public Shared Function Metodo()
        Return "Biblioteca1.Class1.Metodo"
    End Function
End Class

Faremos exatamente a mesma coisa na “Class1” da “Biblioteca2“, porém, nesse caso o método deverá retornar a string contendo “Biblioteca2.Class1.Metodo“:

// C#
namespace Biblioteca2
{
    public class Class1
    {
        public static string Metodo()
        {
            return "Biblioteca2.Class1.Metodo";
        }
    }
}
' VB.NET
Public Class Class1
    Public Shared Function Metodo()
        Return "Biblioteca2.Class1.Metodo"
    End Function
End Class

Em seguida, vamos adicionar as referências para “Biblioteca1” e “Biblioteca2” no nosso projeto “Console Application“. Para isso, temos que clicar com o botão direito em “References” e escolher os projetos que estarão listados dentro da categoria “Projects“:

Por fim, vamos até a classe “Program” (ou “Module1” no VB.NET), onde imprimiremos o resultado das chamadas para os métodos das bibliotecas:

        // C#
        static void Main(string[] args)
        {
            Console.WriteLine(Biblioteca1.Class1.Metodo());
            Console.WriteLine(Biblioteca2.Class1.Metodo());
            Console.ReadLine();
        }
    ' VB.NET
    Sub Main()
        Console.WriteLine(Biblioteca1.Class1.Metodo())
        Console.WriteLine(Biblioteca2.Class1.Metodo())
        Console.ReadLine()
    End Sub

Execute a solução e veja o resultado na janela de console:

Nada sofisticado, não é mesmo? Porém, se dermos uma olhada no diretório de saída da solução (onde os projetos são compilados), veremos que temos 3 assemblies (um executável e duas dlls):

Isso quer dizer que a aplicação só funcionará no computador do cliente caso tivermos todos esses arquivos distribuídos na pasta da aplicação. Lembre-se que neste artigo estamos falando de uma solução extremamente simples. Imagine em um cenário real onde diversas bibliotecas são utilizadas nos nossos projetos? A quantidade de assemblies que devem ser distribuídos pode ser bem grande e isso pode se tornar um problema. É por isso que o ILMerge foi desenvolvido: para juntar todos os assemblies em um único executável ou dll!

Baixando e utilizando o ILMerge via linha de comando

O ILMerge pode ser baixado no Download Center da Microsoft ou no formato de um pacote NuGet. Nesta seção do artigo eu vou utilizar a opção do pacote NuGet. Para instalá-lo no seu projeto, abra a janela “Manage NuGet Packages” e procure por “ILMerge“:

Outra opção é digitar o comando “Install-Package ilmerge” diretamente no NuGet Package Manager. Se você tiver alguma dúvida sobre esse processo, confira este artigo onde eu mostro como gerenciar pacotes do NuGet no Visual Studio.

Uma vez instalado, o executável do NuGet estará disponível dentro do subdiretório “packages\ilmerge.2.14.1208\tools” da nossa solução:

Para facilitar a nossa vida, vamos copiar esse executável para a pasta de saída da nossa solução (bin\debug) e, em seguida, vamos abrir um prompt de comando nesse diretório. A propósito, você sabia que dá para abrir um prompt de comando dentro de um diretório específico através do Windows Explorer? Saca só:

Com o prompt de comando aberto, vamos entender a sintaxe básica do ILMerge. Primeiramente, temos que indicar o tipo de saída através do argumento “/target“. Existem três opções para esse argumento: “library“, “exe” ou “winexe“. A opção “library” gerará uma dll, já as opções “exe” e “winexe” gerarão um executável. Mas, qual é a diferença entre essas duas opções que geram executáveis? Simples: a opção “exe” gera um executável do tipo “Console Application” e a opção “winexe” gera um executável do tipo “aplicação Windows” (Windows Forms / WPF). Se você confundir esses dois tipos de executável, a aplicação não funcionará.

Em seguida, com o argumento “/out” nós temos que definir o nome do arquivo de destino. No nosso exemplo, nós utilizaremos o nome “Executavel.exe“. Por fim, temos que passar a lista dos arquivos que deverão ser mesclados (no nosso caso, “ExemploILMerge.exe“, “Biblioteca1.dll” e “Biblioteca2.dll“).

Veja como fica a linha de comando para mesclarmos os arquivos da nossa solução:

ILMerge.exe /target:exe /out:Executavel.exe ExemploILMerge.exe Biblioteca1.dll Biblioteca2.dll

Ao executarmos essa linha de comando, teremos o novo executável gerado na pasta bin\debug:

Teste a execução dessa nova aplicação e veja que o comportamento é exatamente o mesmo da aplicação original. Entretanto, agora nós não precisamos mais distribuir três assemblies separados. Basta distribuirmos o arquivo “Executavel.exe” nos computadores clientes e tudo deve funcionar perfeitamente.

Utilizando a ferramenta visual ILMergeGui

Muito legal esse esquema do ILMerge, mas, trabalhar com linha de comando muitas vezes acaba enchendo o saco, não é mesmo? Imagine uma solução onde tenhamos que mesclar 30 assemblies. Vamos ter que digitar o nome dos 30 assemblies na linha de comando? Nada prático.

Foi pensando nisso que uma galera da comunidade resolveu desenvolver uma interface gráfica para o ILMerge. Por trás dos panos o “ILMerge.exe” será chamado passando os argumentos corretos de acordo com o que foi escolhido na interface visual. Essa interface gráfica é chamada ILMergeGui.

Uma vez instalada e executada, pode ser que você receba este erro:

Esse erro acontece quando utilizamos o ILMerge através do pacote NuGet (ao invés de instalarmos pelo Download Center da Microsoft). Nesse caso, o ILMergeGui não consegue encontrar o “ILMerge.exe” e acaba dando esse erro. Para resolvermos esse contratempo, temos três opções:

1) Instalar o ILMerge utilizando o instalador baixado no Download Center
2) Copiar o ILMerge.exe para o diretório C:\Windows\System32
3) Copiar o ILMerge.exe para dentro do diretório de instalação do ILMergeGui

Eu recomendo que você utilize a primeira ou segunda opções. O ILMergeGui é instalado através do ClickOnce, portanto, o seu diretório de instalação fica nas entranhas do sistema de arquivos, o que dificulta um pouco a localização do diretório para utilizarmos a terceira alternativa. No meu computador, por exemplo, o ILMergeGui foi instalado dentro deste diretório: “C:\Users\andrealveslima\AppData\Local\Apps\2.0\TKL4XB63.2CN\TLE58ZPL.D5G\ilme..tion_f70b3bef76080fc4_0002.0000_182dad39646c61d9“:

Enfim, com esse contratempo resolvido, ao abrirmos o ILMergeGui novamente, nós não receberemos mais nenhuma mensagem de erro. A interface do ILMergeGui é muito simples. Na parte de cima (“Assemblies to merge“) nós temos que arrastar os arquivos que devem ser mesclados (no nosso caso ExemploILMerge.exe, Biblioteca1.dll e Biblioteca2.dll) e na parte inferior (“Output assembly“) nós escolhemos o caminho e o nome do executável ou dll onde o resultado deverá ser gerado:

Aí é só clicar em “Merge” e pronto! Bem mais fácil do que trabalhar com o ILMerge via linha de comando, não é mesmo?

Concluindo

A ferramenta ILMerge serve para mesclarmos vários assemblies (.exe e .dll) em um único assembly. Isso pode ser muito útil nas situações em que as nossas aplicações possuam muitas referências a dlls externas.

No artigo de hoje você conferiu como juntar executável e dlls em um arquivo só utilizando o ILMerge. Você viu também que o ILMerge só trabalha com linha de comando, porém, com a ferramenta ILMergeGui, nós temos à nossa disposição uma interface visual que facilita bastante a nossa vida.

E você, já precisou juntar vários assemblies em um só arquivo? Você utilizou o ILMerge ou alguma outra ferramenta? Tudo funcionou certinho ou você enfrentou algum desafio na distribuição dos seus aplicativos? Espero os seus comentários logo abaixo!

Por fim, convido você a inscrever-se na minha newsletter. Ao fazer isso, você receberá um e-mail toda semana sobre o artigo publicado e ficará sabendo também em primeira mão sobre o artigo da próxima semana, além de receber dicas “bônus” que eu só compartilho por e-mail. Inscreva-se utilizando o formulário logo abaixo.

Até a próxima!

André Lima

Image by Pixabay used under Creative Commons
https://pixabay.com/en/connect-connection-cooperation-20333/

Newsletter do André Lima

* indicates required



Powered by MailChimp

12 thoughts on “Juntando executável e dlls em um arquivo só com o ILMerge

  • Emanuel disse:

    Muito bom este artigo gostei,muito obrigado amigao..espero a próxima postarem forte abraço

  • Bom dia André, eu li seu artigo mas fiquei com dúvida, fazendo isso minha aplicação perde desempenho? Tem alguma diferença de performance de usar e não usar? Seria somente o fato de organizar mesmo? Obrigado abraço.

  • Charles Cruz disse:

    Conheci seu blog hoje e já aprendi dois recursos incríveis, ótima didática, conteúdo interessante e diferenciado, parabéns.

  • Jefferson Barbosa disse:

    Bom dia André.

    Estou passando por essas dores “hahahahah” Temos um projeto com vários projetos webforms e alguns projetos class libary que geram algumas dlls.
    Você saberia me dizer se esse ilmerge faria a mesma função na hora do publish?

    Obrigado.

    • andrealveslima disse:

      Olá Jefferson!

      Eu nunca precisei fazer esse merge em projetos web.. Teoricamente deveria funcionar, mas não sei como configurar para ser feito antes do build.. Mas, tem um esquema nas configurações de publish de projetos web que aparentemente faz isso.. Você já chegou a dar uma pesquisada? Veja esta thread nos fóruns:

      Web Publish and Merging Assemblies

      Abraço!
      André Lima

  • João Victor Bibiano Pinheiro disse:

    André, boa tarde. É possível fazer o merge de aplicações 4.7? Recebi um erro “cannot merge .net 4.7 with ilmerge”

    • andrealveslima disse:

      Olá João!

      Eu particularmente nunca testei, porém, dando uma pesquisada sobre essa mensagem de erro, parece que tem um problema de compatibilidade da ferramenta visual do ILMerge no Windows 10 e .NET 4.7.. Veja esta issue no GitHub do ILMerge:

      https://github.com/Microsoft/ILMerge/issues/15

      Você está utilizando a ferramenta visual? Caso positivo, você já tentou efetuar o processo de merge utilizando linha de comando?

      Abraço!
      André Lima

  • luiz carlos disse:

    Como faço para transformar esses arquivos em uma dll ? eles são códigos já prontos para se criar a dll,se puder me dar uma ajuda agradeço demais
    http://prntscr.com/gzdi12

    • andrealveslima disse:

      Olá Luiz!

      Pelo que percebi, esse é um projeto C++ criado no Visual Studio.. Teoricamente, você tem que abrir o arquivo .sln no Visual Studio e compilar o projeto, aí você terá a saída dele (dlls se for realmente o caso desse projeto) no diretório de compilação..

      Abraço!
      André Lima

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *