ILMerge – dołączanie zewnętrznych bibliotek

Rzadko kiedy przy dużych przedsięwzięciach zdarza się trzymanie całego kodu w jednym projekcie (używam tu nomenklatury Visual Studio: solution/project). Duże części kodu używanego w wielu miejscach mogą zostać wydzielone do odrębnych assemblies (tłumaczenie tego słowa jako „zgromadzenie” nie jest zbyt fortunne, dlatego nie będę się bawił w słowotwórstwo i pozostanę przy angielskiej nazwie). Również typowa aplikacja .NET składa się z  assembly wykonywalnej (zawierającej Entry Point aplikacji, czyli tradycyjnej funkcji main()), dodatkowych assemblies w katalogu programu oraz assemblies w GAC (Global Assembly Cache).

Dołączanie do aplikacji dodatkowych, wymaganych plików .dll jest potencjalnym źródłem błędu (nie skopiowanie wszystkich plików, błąd podczas kopiowania któregokolwiek z plików, skopiowanie zewnętrznych bibliotek do niewłaściwego katalogu – przyczyny można mnożyć). Dlatego jest czasem rozsądniej połączyć aplikację oraz zewnętrzne assemblies (w postaci plików dll) w jeden plik wykonywalny.

Służy do tego narzędzie Microsoftu o nazwie ILMerge (do ściągnięcia darmowo ze strony Microsoft’u). Korzystałem z niego przy pisaniu aplikacji eksportującej dane do plików Excel’a (więcej tutaj: http://przemyslawczatrowski.com/2010/03/27/c-eksport-danych-do-pliku-xls/), gdzie dołączałem do pliku wykonywalnego biblioteki Interop umożliwiające korzystanie z Excela w C#. Poniżej opis użycia narzędzia ILMerge.

ILMerge to aplikacja konsolowa. Po zainstalowaniu w katalogu (domyślnie „C:\Program Files\Microsoft\ILMerge”) pojawiają się trzy pliki: ILMerge.exe, ILMerge.doc (dokumentacja) oraz ILMerge Licence.rtf (licencja, o dziwo). W dokumentacji opisane są szczegółowo wszystkie możliwe parametry wywołań, ja skupię się na podstawowej funkcjonalności.

ILMerge.exe /out:MyApplication.exe /target:winexe MyApplication.exe MyExternalLib1.dll MyExternalLib2.dll

warto dodać ścieżkę do katalogu z ILMerge.exe do zmiennej środowiskowej PATH, skróci to zapis wywołania programu. Zajmijmy się kolejnymi parametrami wywołania:

/out:MyApplication.exe

Intuicyjnie – nazwa pliku będącego wynikiem łączenia assemblies (Uwaga: może to być zupełnie nowa nazwa)

/target:winexe

Opcja pozwala zdefiniować typ powstałej assembly, możliwe wartości dla parametru to library (biblioteka dll), exe (plik wykonywalny aplikacji konsolowej), winexe (plik wykonywalny aplikacji Windows Forms).

MyApplication.exe MyExternalLib1.dll MyExternalLib2.dll

Nazwy kolejnych assemblies do połączenia w jedną. Pierwsza pozycja na liście jest to tzw. „primary assembly„, która definiuje rodzaj pliku wynikowego. Jeżeli primary assembly jest biblioteką, to plik wynikowy również nią będzie, jeżeli plikiem wykonywalnym – wynik również będzie plikiem wykonywalnym. Pozostałe pozycje na liście to secondary assemblies, które mają zostać włączone do wynikowego pliku.

Tak proste wywołanie teoretycznie wystarczy, ale przydałoby się kilka usprawnień, pierwszym będzie możliwość dołączenia do pliku exe wszystkich plików .dll z bieżącego katalogu za pomocą użycia „wildcards”. Modyfikujemy poprzednie wywołanie:

ILMerge.exe /out:MyApplication.exe /target:winexe /wildcards MyApplication.exe *.dll

Kolejna modyfikacja jest związana z przeszukiwaniem zewnętrznych katalogów w poszukiwaniu plików, służy do tego parametr „/lib:scieżka_do_katalogu” (WAŻNE: aby dodać ścieżki do kilku różnych katalogów należy dla każdego z nich oddzielnie dodać parametr /lib). Zmodyfikowane wywołanie:

ILMerge.exe /out:MyApplication.exe /target:winexe /wildcards /lib:C:\MyDllDir1 /lib:E:\MyDllDir2 MyApplication.exe *.dll

W powyższym przypadku do wynikowego assembly zostaną dołączone wszystkie pliki .dll z katalogów C:\MyDllDir1 oraz C:\MyDllDir2.

Logowanie czynności wykonywanych przez ILMerge można uzyskać przez podanie parametru /log z opcjonalną nazwą pliku z logiem.

ILMerge.exe /log:ILMergeLog.txt /out:MyApplication.exe /target:winexe /wildcards /lib:C:\MyDllDir1 /lib:E:\MyDllDir2 MyApplication.exe *.dll

To według mnie podstawowe parametry programu, o reszcie można poczytać w dokumentacji.

Na koniec mały, acz przydatny hint pozwalający na automatyzację procesu budowania pisanej przez nas aplikacji. Aby dołączać biblioteki do wynikowego pliku exe naszej aplikacji po każdorazowym wykonaniu polecenia build, wystarczy dobrać się do opcji projektu w Visual Studio (tu na przykładzie Visual C# 2008 Express Edition). Po otwarciu okna opcji projektu należy przejść do zakładki „Build Events” i w polu „Post-build event command line:” wpisać wywołanie komendy odpowiedzialnej za łączenie assemblies. Tylko tyle i aż tyle.

BuildOptions

Na czerwono zaznaczyłem miejsce umieszczenia kodu. Warto zwrócić również uwagę na opcję „Run the post-build event”, ustawienie jej na „On successful build” spowoduje (jak sama nazwa wskazuje),  że wywołanie ILMerge nastąpi dopiero po pomyślnym zbudowaniu aplikacji, jakiekolwiek błędy spowodują nieuruchomienie (bądź co bądź co najmniej kilkusekundowego) procesu.

Be Sociable, Share!
czoper opublikowano dnia 2010-4-1 Kategoria: Aplikacje | Tagi:, ,

Odpowiedzi: 3 Zostaw komentarz

  1. #3ppp @ 2012-3-30 07:43

    Czy jest możliwość debugowania takiej wynikowej dll’ki z poziomu podpięcia pod process (attach to process)?

  2. #2Amy @ 2010-6-6 15:50

    spoko art, kiedys bym bardzo na nim skorzystal 🙂 Jedyne co mozna by dodac to zamiast wpisywac reczenie 15 tys. parametrow 😉 i kazda biblioteke do skladni komendy to lepiej skorzystac z tego rozwiazania dla Visual Studio: http://blogs.msdn.com/jomo_fisher/archive/2006/03/05/544144.aspx

    Pozdr.

  3. #1bincoder @ 2010-4-10 11:44

    spoko art, kiedys bym bardzo na nim skorzystal 🙂 Jedyne co mozna by dodac to zamiast wpisywac reczenie 15 tys. parametrow 😉 i kazda biblioteke do skladni komendy to lepiej skorzystac z tego rozwiazania dla Visual Studio: http://blogs.msdn.com/jomo_fisher/archive/2006/03/05/544144.aspx

    Pozdr.

Zostaw odpowiedź

(Ctrl + Enter)