Visual C# — wbudowujemy elementy

Visual C# — wbudowujemy elementy
Razem głosów: 4 co stanowi: 100% całości.

imgres

Często w naszym programie zachodzi konieczność zastosowania zewnętrznych bibliotek do różnych celów np do obsługi czegoś tam … tak tak wiem zacząłem z dziwnej strony … niemniej zaraz wszystko stanie się jasne ….

 

W zasadzie mamy w przypadku używania zewnętrznych bibliotek x.dll dwie możliwości:

1. Dodajemy w projekcie Odwołanie do biblioteki i we właściwościach odwołania (reference) zaznaczamy żeby była wykonana kopia lokalna

– spowoduje to że po kompilacji do folderu zostanie zapisany plik dll i będzie można tak jej używać z pliku dll z folderu programu .

Rozwiązanie jest dobre i często się takie stosuje. Niemniej czasem jest mało wygodne , czasem chcemy też by nasz program nie zawierał zbyt wielu plików ….

Co możemy więc z tym zrobić ??
— ano całkiem sporo

W tym poradniku zajmiemy się osadzaniem bibliotek dll w pliku exe.

Powiecie pewnie jaki ma to cel i sens ….
No spory – zwłaszcza gdy chcemy by nasz program był przenośny zobaczmy więc co tak naprawdę nam daje ….

——– ZALETY

  • – ułatwia dystrybucję programu wśród użytkowników jeden plik – zamiast wielu
  • – wymagane pliki dll nie zostaną przypadkiem pominięte przez użytkownika ,
  • – w przypadku niektórych bibliotek może się pojawić nowa wersja
  • – użytkownik będzie wolał pobrać jeden plik niż np ręcznie zmieniać pliki dll.

Jak widać to dużo , ale metoda ma też wadę może w dobie dzisiejszych komputerów nie aż tak istotną , ale jednak…

– wymaga więcej pracy od programisty i wymusza podjęcie dodatkowych kroków w celu scalenia plików, a keżde nowe wydanie dla danego dll jeśli jest to konieczne w aplikacji wymaga jej przepakowanie …

———————————————————————————————-

Osadzanie plików *.dll jest używane przez programy instalatorów powiecie , przecież też są w jednym pliku. Tak to prawda , ale nasza aplikacja nie wymaga instalacji jest za mała , po za tym przecież nie robimy tradycyjnego śmietnika na dysku rozrzucając pliki po całym dysku i rejestrze.

Zróbmy to tak jak powinno się to robić i jak to było wykonywane w porządnych systemach …

Dobrze …. zatem stwórzmy nowy projekt i nazwijmy go … wbudowana_biblioteka
następnie jakieś biblioteki :

a niech to będzie np System.Windows.Forms.Ribbon35.DLL z http://officeribbon.codeplex.com
oraz System.Data.SQLite.DLL z http://system.data.sqlite.org

to dobra okazja bowiem pierwsza zawiera pakiet komponentów, a druga obsługę bazy danych i się różnią – pierwsza jest zarządzalna , a druga nie ,oznacza to że do pierwszej poza wywołaniem funkcji przekazujemy parametry , a z drugiej tylko
wywołujemy funkcje. Dobra mamy już nasz projekt i biblioteki. i Co teraz ??

A no nic …

gdy już mamy nasz projekt dodajemy odwołanie do naszych bibliotek.
jest to banalnie proste , klikamy RMB na Odwołania i z meny wybieramy Dodaj odwołanie
pojawi się nam okienko:

d74168d7f1315d03f7784d883d36e521

gdzie w zakładce przeglądaj wybieramy nasze biblioteki po kolei i klikamy OK ….
Odwołania mamy z głowy … pojawiły się …

9a4bd4f656aa299eeaf4942f56f0461a

W zasadzie od teraz możemy już używać w naszym programie już bibliotek o czym wspomniałem na początku wymaga to tylko dodania bibliotek do pliku wykonywalnego … (do ProgDira) co możemy ja wspominałem zrobić we właściwościach odwołania :

73cd731d0d8df9adcf6697e918bb798d

zmieniając wartość pola Kopia lokalna na true — co spowoduje skopiowanie pliku dll do folderu kompilacji (dołączenie do programu).
Ale nas to nie interesuje ….mu chcemy nasze biblioteki zaszyć w pliku exe….

Zatem teraz musimy nasze pliki dll dodać do projektu…
Możemy to zrobić na 2 sposoby…

1. kliknąć RMB na nazwie projektu i wybrać dodaj – istniejący element lub Shift-Alt-A i wybrać nasze pliki dll
2. Przeciągnąć je na projekt np z pulpitu lub lokalizacji projektu i upuścić (drag&drop)

ma to wyglądać tak:

d28eb18e16a69c4552e57849c3c6da8b

Teraz będzie trudniej ….

Przede wszystkim w odwołaniu do biblioteki kopia lokalna ma być false — co widać wyżej …. (nie będziemy kopiować bibliotek)
Teraz klikamy na naszych plikach DLL w eksploratorze projektu i w ich właściwościach …..

405b971337afc53886db9bf0a22a6f83

Dla obu plików .dll zmieniamy wartość pola Akcja Kompilacji na Zasób osadzony …..:)
ma to wyglądać dokładnie jak widzicie wyżej…

Uffff … to tyle ….

no nie żartowałem … fakt po kompilacji nasze biblioteki zostaną dołączone do pliku exe, ale nie będą używane i nie zadziała nasz program na kompie bez tych bibliotek ….

Zróbmy więc cokolwiek co zawierają nasze libsy na formie1 :)

ed2db99eb7032ad063413d5c75ce8823

np tak …. dodamy panel z biblioteki Ribon

i sami sprawdźcie … po kompilacji że bez bibliotek wasz program nie działa …. no bo niby jak co .. przecież poza tym ze dodaliśmy je do pliku program nie wie gdzie są i jak je użyć ….

no to do roboty…..

Nasze zadanie jest proste … musimy podczas uruchomienia programu wypakować biblioteki i załadować do programu …

Szukamy w projekcie pliku Program.cs (zawiera on podstawową klase naszego programu) i otwieramy go:

tam znajdujemy funkcję main()

jak widać całość jest jasna …
i dopisujemy ładowanie naszych dll do ram….
co powinno wyglądać tak :

Używamy jak widać metody PaczkaDll.Load by załadować nasze wbudowane biblioteki do pamięci RAM. Zwróćcie też uwagę na format ciągu zasobów:

Wbudowana_biblioteka.System.Data.SQLite.dll

Ciąg ten to jakby adres naszego zasobu. Zawiera nazwę naszego projektu i pliku DLL. trzeba na to uważać gdyż jeśli chcemy np dodać biblioteki w folderze np DLLe to ta nazwa folderu musi byc też uwzględniona w adresie. Ale tu dodajemy tylko czyste pliki dll… niemniej jeśli trzeba to powinno to wyglądać tak:

nazwa_aplikacji.nazwa_folderu.System.Data.SQLite.dll

zdarzenie AppDomain.CurrentDomain.AssemblyResolve.. jest przydatne w wypadku gdy biblioteki nie mogą być zlokalizowane przez aplikację do dystrybucji. AssemblyResolve wywołuję żądanie plików DLL , których brakuje. Musimy więc jej powiedzieć że nasze biblioteki są w pamięci RAM, w tym celu użyjemy metody PaczkaDll.Get by pobrać biblioteki z pamięci i przekazać je do AssemblyResolve, który obsłuży całą resztę …

a więc dopiszmy jeszcze kawałek kodu pod funkcją main()

a cały nasz plik Program.cs powinien wyglądać np tak:

I to by było na tyle ?? –

i tak i nie … gdyż potrzeba nam jeszcze stworzyć klasę PaczkaDll.

w tym celu do naszego projektu dodajemy nową klasę (Shift-Alt-C) i nazywamy ją PaczkaDll.cs. Zatem otwieramy plik i w nim umieszczamy kod:

Powyższy kod zawiera metody ładowania plików DLL które będą używane z .Net
A musimy wiedzieć że mamy dwa typy plików Dll

– Zarządzane DLL
– Niezarządzalne DLL lub Mixed Code DLL

dlatego też procedury ładowania sa odmienne …
W przypadku zarządzalnych DLL procedura ładowania jest prosta i można ją zrealizować np tak:

 

Ale biblioteki niezarządzalnej nie możemy załadować bezpośrednio do tablicy byte[] tak jak zarządzalnej
tu musimy:1. najpierw załadować osadzoną bibliotekę do tablicy byte[]
2. zapisać zawartość tablicy byte[] do fizycznego pliku i przechować w folderze temp
3. użyć metody loadFile() by załadować plik do pamiecico opisałem w komentarzach w kodzie PaczkaDLL.. która to będzie wstępnie ładować wymagane biblioteki DLL i przechowywać je wewnątrz „Słownika”, a gdy nastąpi ewent AssembyResolve metoda PaczkaDll.Get()
zwróci żądaną bibliotekę.

Miłej zabawy z osadzaniem plików….

 

 

 

Podziel się na:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay