2-Bob: Qurish, Paketlash, Deploy va Boshqarish
Ilovalar va turlarni qurish, paketlash, tarqatish va boshqarish usullarini o'rganish
Oldingi bobda siz CLR ning bajarish modelini o'rgandingiz — manba kodi qanday kompilyatsiya qilinishi, IL va metadata nima ekanligi, assembly tushunchasi va boshqalar. Ushbu bobda esa men sizga manba kod faylingizni deploy qilish mumkin bo'lgan faylga qanday aylantirish, turli modullarni assembly sifatida birlashtirish va ilovangizni foydalanuvchilarga qanday yetkazish haqida batafsil gaplashaman.
.NET Framework juda boy deployment modelini taklif qiladi. Bu model shaxsiy deploy qilish (privately deployed assemblies) tushunchasiga asoslanadi — ya'ni assembly fayllarini ilovangiz papkasiga nusxalash kifoya. O'rnatish uchun registrga yozish shart emas, o'chirish uchun esa fayllarni o'chirish kifoya.
.NET Framework shuningdek kod kirish xavfsizligi (code access security) deb ataladigan xavfsizlik modelini o'z ichiga oladi. Windows xavfsizligi foydalanuvchi identifikatsiyasiga asoslangan bo'lsa, kod kirish xavfsizligi xostlarga ruxsatlarni belgilashga, shu bilan yuklangan komponentlarning nima qila olishini nazorat qilishga imkon beradi. SQL Server kabi xost ilovasi faqat bir nechta ruxsatlarni berishi mumkin, mahalliy o'rnatilgan (self-hosting) ilova esa to'liq ishonch (full trust) bilan ishlashi mumkin.
Turlarni Modulga Qurish
Ushbu bo'limda men sizga turli turlarni o'z ichiga olgan manba kod faylingizni deploy qilinadigan faylga qanday aylantirish kerakligini ko'rsataman. Keling, quyidagi oddiy ilovani ko'rib chiqaylik:
public sealed class Program {
public static void Main() {
System.Console.WriteLine("Hi");
}
}
Bu ilova Program nomli turni aniqlaydi. Bu turda Main nomli bitta ochiq, statik metod bor. Main ichida System.Console nomli boshqa turga havola bor. System.Console — bu Microsoft tomonidan amalga oshirilgan tur bo'lib, uni amalga oshiruvchi IL kodi MSCorLib.dll faylida joylashgan. Demak, bizning ilovamiz ham o'z turini aniqlaydi, ham boshqa kompaniyaning turini ishlatadi.
Ushbu misolni qurish uchun oldingi kodingizni manba kod fayliga, masalan Program.cs ga joylashtiring va quyidagi buyruq qatorini bajarasiz:
csc.exe /out:Program.exe /t:exe /r:MSCorLib.dll Program.cs
Bu buyruq qatori C# kompilyatoriga Program.exe nomli bajariladigan fayl chiqarishni aytadi. Ishlab chiqarilgan fayl turi Win32 konsol ilova (/t[arget]:exe).
C# kompilyatori manba faylni qayta ishlaganda, u kodning System.Console turining WriteLine metodiga murojaat qilishini ko'radi. Bu nuqtada kompilyator ushbu tur biror joyda mavjudligini, uning WriteLine metodiga ega ekanligini va metodga uzatilayotgan argument mos turda ekanligini tekshirishni xohlaydi. Bu tur C# manba kodida aniqlanmaganligi sababli, C# kompilyatorini qoniqtirish uchun unga tashqi turlarga havolalarni hal qilish uchun foydalanishi mumkin bo'lgan assembly to'plamini berishingiz kerak. Oldingi buyruq qatorida men /r[eference]:MSCorLib.dll kalitini qo'shdim, bu kompilyatorga MSCorLib.dll fayli bilan aniqlangan assemblydagi tashqi turlarni qidirish kerakligini aytadi.
MSCorLib.dll maxsus fayl bo'lib, u barcha asosiy turlarni o'z ichiga oladi: Byte, Char, String, Int32 va boshqalar. Aslida, bu turlar shunchalik tez-tez ishlatiladiki, C# kompilyatori MSCorLib.dll assemblyga avtomatik ravishda havola qiladi. Boshqacha aytganda, quyidagi buyruq qatori (/r kalitisiz) ham oldingi bilan bir xil natijani beradi:
csc.exe /out:Program.exe /t:exe Program.cs
Bundan tashqari, /out:Program.exe va /t:exe buyruq qatori kalitlari C# kompilyatorining standart tanlovlariga mos kelganligi sababli, quyidagi buyruq qatori ham bir xil natijani beradi:
csc.exe Program.cs
Agar biron sababga ko'ra C# kompilyatoriga MSCorLib.dll assemblyga havola qildirishni xohlamasangiz, /nostdlib kalitini ishlatishingiz mumkin. Masalan, quyidagi buyruq qatori xato beradi, chunki System.Console turi MSCorLib.dll da aniqlangan:
csc.exe /out:Program.exe /t:exe /nostdlib Program.cs
Endi C# kompilyatori tomonidan ishlab chiqarilgan Program.exe faylini yaqinroq ko'rib chiqaylik. Bu fayl aslida nima? Birinchidan, u standart portativ bajariladigan (PE) fayldir. Bu 32-bit yoki 64-bit Windows versiyalarini ishlatuvchi mashina bu faylni yuklashi va u bilan biror narsa qila olishi kerakligini anglatadi. Windows uchta turdagi ilovalarni qo'llab-quvvatlaydi: konsol foydalanuvchi interfeysi (CUI) ilovasi qurish uchun /t:exe, grafik foydalanuvchi interfeysi (GUI) ilovasi qurish uchun /t:winexe, va Windows Store ilovasi qurish uchun /t:appcontainerexe kalitini belgilang.
Response Fayllar
Kompilyator kalitlari haqidagi muhokamani tugatishdan oldin, men response fayllar haqida qisqacha gapirmoqchiman. Response fayl — kompilyator buyruq qatori kalitlari to'plamini o'z ichiga olgan matn fayli. Siz CSC.exe ni bajarganda, kompilyator response fayllarni ochadi va ulardagi kalitlarni xuddi CSC.exe buyruq qatoriga yozilgandek ishlatadi. Kompilyatorga response faylni buyruq qatorida uning nomini @ belgisi bilan boshlab ko'rsatasiz. Masalan, MyProject.rsp nomli response faylingiz quyidagi matnni o'z ichiga olishi mumkin:
/out:MyProject.exe
/target:winexe
CSC.exe ga bu sozlamalarni ishlatishni aytish uchun, uni quyidagicha chaqirasiz:
csc.exe @MyProject.rsp CodeFile1.cs CodeFile2.cs
Bu C# kompilyatoriga chiqish faylining nomini va yaratish kerak bo'lgan nishon turini aytadi. Ko'rib turganingizdek, response fayllar juda qulay, chunki har safar loyihangizni kompilyatsiya qilmoqchi bo'lganingizda buyruq qatori argumentlarini qo'lda yozishingiz shart emas.
C# kompilyatori bir nechta response fayllarni qo'llab-quvvatlaydi. Buyruq qatorida aniq ko'rsatilgan fayllardan tashqari, kompilyator avtomatik ravishda CSC.rsp nomli fayllarni qidiradi. CSC.exe ni ishga tushirganingizda, u CSC.exe faylini o'z ichiga olgan papkada global CSC.rsp faylni qidiradi. Barcha loyihalaringizga tegishli sozlamalar shu faylga joylashtirilishi kerak.
.NET Framework o'rnatilganda, u %SystemRoot%\Microsoft.NET\Framework(64)\vX.X.X papkasida standart global CSC.rsp faylini o'rnatadi. Bu faylning oxirgi versiyasi ko'plab umumiy assemblylarga /r havolalarini o'z ichiga oladi, masalan: System.dll, System.Data.dll, System.Xml.dll, System.Windows.Forms.dll va boshqalar.
Global CSC.rsp fayl ro'yxatda keltirilgan barcha assemblylarga havola qilganligi sababli, C# kompilyatorining /reference kaliti yordamida bu assemblylarni alohida ko'rsatishingiz shart emas. Bu response fayl dasturchilar uchun katta qulaylik yaratadi, chunki ularga turli Microsoft nashriyot assemblylarida aniqlangan turlar va nomlar fazolarini ishlatish imkonini beradi.
Assembly ga havola qilish uchun /reference kompilyator kalitini ishlatganingizda, ma'lum bir faylga to'liq yo'lni belgilashingiz mumkin. Biroq, agar yo'lni belgilamasangiz, kompilyator faylni quyidagi joylarda (ko'rsatilgan tartibda) qidiradi:
- Ishchi papka (Working directory)
- CSC.exe faylini o'z ichiga olgan papka. MSCorLib.dll har doim shu papkadan olinadi.
/libkompilyator kaliti yordamida ko'rsatilgan papkalarLIBmuhit o'zgaruvchisi yordamida ko'rsatilgan papkalar
Albatta, global CSC.rsp fayliga o'z kalitlaringizni qo'shishingiz mumkin, lekin bu turli qurilish mashinalari o'rtasida qurilish muhitini ko'chirish qiyinlashadi. Shuningdek, kompilyatorga mahalliy va global CSC.rsp fayllarini e'tiborsiz qoldirishni /noconfig buyruq qatori kalitini belgilab aytishingiz mumkin.
Metadata ga Qisqacha Nazar
Endi biz yaratgan PE fayl qanday ekanligini bilamiz. Lekin Program.exe faylida aynan nima bor? Boshqariladigan PE fayl to'rtta asosiy qismdan iborat: PE32(+) sarlavha, CLR sarlavha, metadata va IL.
PE32(+) sarlavha — Windows kutadigan standart ma'lumot. CLR sarlavha — boshqariladigan modullarga (CLR talab qiladigan modullarga) xos ma'lumotlarning kichik bloki. Sarlavha modulning qurulgan CLR ning asosiy va ikkinchi darajali versiya raqamini, ba'zi flaglarni, modulning kirish nuqtasi metodini ko'rsatuvchi MethodDef tokenini (keyinroq tasvirlangan) va ixtiyoriy kuchli nomli raqamli imzo (3-bobda muhokama qilinadi) ni o'z ichiga oladi. Nihoyat, sarlavha modul ichidagi ma'lum metadata jadvallarining hajmi va ofsetlarini o'z ichiga oladi.
Metadata — bir nechta jadvallardan iborat ikkilik ma'lumotlar bloki. Jadvallarning uchta toifasi mavjud: aniqlash jadvallari, havola jadvallari va manifest jadvallari. 2-1 jadval modul metadata blokidagi eng keng tarqalgan aniqlash metadata jadvallarini tavsiflaydi.
| Metadata aniqlash jadvali nomi | Tavsif |
|---|---|
| ModuleDef | Har doim modulni identifikatsiya qiluvchi bitta yozuvni o'z ichiga oladi. Yozuv modulning fayl nomi va kengaytmasini (yo'lsiz) va modul versiya ID sini (kompilyator tomonidan yaratilgan GUID shaklidagi) o'z ichiga oladi. |
| TypeDef | Modulda aniqlangan har bir tur uchun bitta yozuv. Yozuv turning nomi, asosiy turi, flaglari (public, private va hokazo) va MethodDef, FieldDef, PropertyDef, EventDef jadvallaridagi a'zolariga indekslarni o'z ichiga oladi. |
| MethodDef | Modulda aniqlangan har bir metod uchun bitta yozuv. Yozuv metod nomi, flaglari (private, public, virtual, abstract, static, final va hokazo), imzosi va IL kodining modul ichidagi ofsetini o'z ichiga oladi. |
| FieldDef | Modulda aniqlangan har bir maydon uchun bitta yozuv. Yozuv flaglari (private, public va hokazo), turi va nomini o'z ichiga oladi. |
| ParamDef | Modulda aniqlangan har bir parametr uchun bitta yozuv. Flaglari (in, out, retval va hokazo), turi va nomini o'z ichiga oladi. |
| PropertyDef | Modulda aniqlangan har bir xususiyat uchun bitta yozuv. Flaglar, tur va nomini o'z ichiga oladi. |
| EventDef | Modulda aniqlangan har bir hodisa uchun bitta yozuv. Flaglar va nomini o'z ichiga oladi. |
Kompilyator manba kodingizni kompilyatsiya qilganda, kodingizda aniqlaydigan har bir narsa 2-1 jadvalda tasvirlangan jadvallarning birida yozuv yaratishga sabab bo'ladi. Metadata jadval yozuvlari kompilyator manba koddagi turlar, maydonlar, metodlar, xususiyatlar va hodisalarni aniqlaganda ham yaratiladi. Yaratilgan metadata shuningdek havola qilingan elementlarning yozuvini saqlovchi havolalar jadvallari to'plamini ham o'z ichiga oladi. 2-2 jadval keng tarqalgan havolalar metadata jadvallarini ko'rsatadi.
| Metadata havola jadvali nomi | Tavsif |
|---|---|
| AssemblyRef | Modul tomonidan havola qilingan har bir assembly uchun bitta yozuv. Yozuv assemblyga bog'lanish uchun zarur ma'lumotlarni o'z ichiga oladi: assembly nomi, versiya raqami, madaniyat va ochiq kalit tokeni. |
| ModuleRef | Ushbu modul tomonidan havola qilingan turlarni amalga oshiruvchi har bir PE moduli uchun bitta yozuv. Yozuv modulning fayl nomi va kengaytmasini o'z ichiga oladi. |
| TypeRef | Modul tomonidan havola qilingan har bir tur uchun bitta yozuv. Yozuv turning nomi va turni qayerda topish mumkinligiga havolani o'z ichiga oladi. |
| MemberRef | Modul tomonidan havola qilingan har bir a'zo (maydonlar, metodlar, xususiyat va hodisa metodlari) uchun bitta yozuv. Yozuv a'zo nomi, imzosi va a'zoni aniqlagan TypeRef yozuviga ko'rsatkichni o'z ichiga oladi. |
Turli vositalar boshqariladigan PE fayl ichidagi metadatani tekshirishga imkon beradi. Men hali ham tez-tez ishlatadigan vositalardan biri — ILDasm.exe (IL Disassembler). Metadata jadvallarini ko'rish uchun quyidagi buyruq qatorini bajaring:
ILDasm Program.exe
Bu ILDasm.exe ni ishga tushiradi va Program.exe assemblyni yuklaydi. Metadatani chiroyli, odam o'qiy oladigan ko'rinishda ko'rish uchun View/MetaInfo/Show! menyu elementini tanlang (yoki Ctrl+M tugmasini bosing).
ILDasm chiqishidan muhim narsa — Program.exe faylida Program nomli TypeDef mavjud. Bu tur System.Object dan hosila bo'lgan ochiq, muhrlangan (sealed) klass ekanligini ko'rsatadi. Program turi ikkita metodni aniqlaydi: Main va .ctor (konstruktor).
Main — ochiq, statik metod bo'lib, uning kodi native CPU kodiga emas, balki IL ga tegishli. Main ning qaytarish turi void va hech qanday argumentlari yo'q. Konstruktor metodi (.ctor) ochiq, kodi ham IL, void qaytarish turiga ega, argumentlari yo'q, lekin this ko'rsatkichiga ega — bu metod chaqirilganida quriladigan obyektning xotirasiga ishora qiladi.
Men sizga ILDasm bilan tajriba o'tkazishni jiddiy tavsiya qilaman. U sizga juda ko'p ma'lumotni ko'rsata oladi va siz ko'rayotgan narsani qanchalik tushunsangiz, CLR va uning imkoniyatlarini shunchalik yaxshi tushunasiz.
Qiziq fakti uchun, keling Program.exe assemblysining ba'zi statistikasini ko'rib chiqaylik. ILDasm ning View/Statistics menyu elementini tanlaganingizda, fayl hajmi (baytlarda) va faylni tashkil etuvchi turli qismlarning hajmi va foizlari ko'rsatiladi. Ushbu juda kichik Program.cs ilovasi uchun PE sarlavha va metadata faylning asosiy qismini tashkil qiladi. Aslida, IL kod faqat 20 baytni egallaydi.
ILDasm.exe da fayl hajmi ma'lumotlariga ta'sir qiladigan xato mavjud. Xususan, Unaccounted ma'lumotiga ishonib bo'lmaydi.
Modullarni Assemblyga Birlashtirish
Oldingi bo'limda muhokama qilingan Program.exe fayli — bu faqat metadata bilan PE fayl emas; u shuningdek assembly hamdir. Assembly — bu tur ta'riflari va resurs fayllarini o'z ichiga olgan bir yoki bir nechta fayllar to'plami. Assembly fayllarining biri manifest ni saqlash uchun tanlanadi. Manifest — assembly qismidagi fayllarning nomlari, assembly versiyasi, madaniyati, nashriyotchisi, ochiq eksport qilingan turlari va assemblyni tashkil etuvchi barcha fayllar haqidagi ma'lumotlarni o'z ichiga oluvchi yana bir metadata jadvallari to'plamidir.
CLR assemblylar bilan ishlaydi; ya'ni CLR har doim avval manifest metadata jadvallarini o'z ichiga olgan faylni yuklaydi va keyin assemblydagi boshqa fayllarning nomlarini olish uchun manifest dan foydalanadi. Assemblylarning ba'zi xususiyatlari:
- Assembly qayta foydalaniladigan turlarni aniqlaydi.
- Assembly versiya raqami bilan belgilanadi.
- Assembly xavfsizlik ma'lumotiga ega bo'lishi mumkin.
Assembly ning individual fayllarida bu atributlar yo'q — faqat manifest o'z ichiga olgan faylda mavjud.
Turlarni paketlash, versiyalash, himoyalash va foydalanish uchun, ularni assembly qismidagi modullarga joylashtirishingiz kerak. Ko'p hollarda assembly bitta fayl sifatida bo'ladi, xuddi oldingi Program.exe misolida bo'lgani kabi. Biroq, assembly bir nechta PE fayllarni metadata bilan va ba'zi resurs fayllarni (.gif yoki .jpg fayllar kabi) ham o'z ichiga olishi mumkin. Assembly ni mantiqiy EXE yoki DLL deb tasavvur qilishingiz yordam berishi mumkin.
Ko'p faylli assemblylarni ishlatishning uchta sababini ajratib ko'rsataman:
- Turlarni alohida fayllarga ajratish — fayllarni bosqichma-bosqich yuklash imkonini beradi (Internet orqali yuklab olish stsenariysida foydali).
- Resurs yoki ma'lumot fayllarini qo'shish — masalan, sug'urta hisoblarini amalga oshiruvchi tur uchun aktuarial jadvallarni alohida fayl sifatida qo'shish mumkin.
- Turli dasturlash tillarida yozilgan turlarni birlashtirish — ba'zi turlarni C# da, boshqalarini Visual Basic da amalga oshirishingiz va ularni bitta assemblyga birlashtirishingiz mumkin.
Xulosa qilib aytganda, assembly — qayta foydalanish, versiyalash va xavfsizlikning bir birligi. U sizga turlaringiz va resurslaringizni alohida fayllarga bo'lish, qaysi fayllarni birgalikda paketlash va deploy qilishni aniqlash imkonini beradi. CLR manifest o'z ichiga olgan faylni yuklaydi va keyin assemblyning boshqa fayllarini aniqlaydi. Assemblyni ishlatayotgan har kim faqat manifest o'z ichiga olgan faylning nomini bilishi kerak.
Agar sizda bitta versiya raqami va xavfsizlik sozlamalarini almasha oladigan bir nechta turlar bo'lsa, barcha turlarni alohida fayllarga yoyish o'rniga bitta faylga joylash tavsiya etiladi. Sababi — unumdorlik. Faylni/assemblyni yuklash CLR va Windows uchun vaqt talab qiladi. Kam fayllar/assemblylar yuklash — yaxshiroq unumdorlik.
Assembly qurish uchun PE fayllaringizdan birini manifest saqlovchisi sifatida tanlashingiz kerak. Yoki manifest dan boshqa hech narsani o'z ichiga olmagan alohida PE fayl yaratishingiz mumkin. 2-3 jadval boshqariladigan modulni assemblyga aylantiruvchi manifest metadata jadvallarini ko'rsatadi.
| Manifest metadata jadvali nomi | Tavsif |
|---|---|
| AssemblyDef | Agar ushbu modul assemblyni identifikatsiya qilsa, bitta yozuvni o'z ichiga oladi. Yozuv assembly nomi (yo'l va kengaytmasiz), versiyasi (major, minor, build, revision), madaniyati, flaglari, xesh algoritmi va nashriyotchining ochiq kalitini o'z ichiga oladi. |
| FileDef | Assembly qismidagi har bir PE va resurs fayli uchun bitta yozuv (manifest o'z ichiga olgan fayldan tashqari). Yozuv fayl nomi va kengaytmasini (yo'lsiz), xesh qiymatini va flaglarini o'z ichiga oladi. |
| ManifestResourceDef | Assembly qismidagi har bir resurs uchun bitta yozuv. Yozuv resurs nomi, flaglari (public yoki private) va FileDef jadvalidagi indeksni o'z ichiga oladi. |
| ExportedTypesDef | Assembly PE modullaridan eksport qilingan har bir ochiq tur uchun bitta yozuv. Yozuv tur nomi, FileDef jadvalidagi indeks va TypeDef jadvalidagi indeksni o'z ichiga oladi. |
C# kompilyatori quyidagi buyruq qatori kalitlaridan birini belgilaganingizda assembly ishlab chiqaradi: /t[arget]:exe, /t[arget]:winexe, /t[arget]:appcontainerexe, /t[arget]:library yoki /t[arget]:winmdobj. Bu kalitlarning barchasi kompilyatorga manifest metadata jadvallarini o'z ichiga olgan bitta PE fayl yaratishga sabab bo'ladi.
Bundan tashqari, C# kompilyatori /t[arget]:module kalitini qo'llab-quvvatlaydi. Bu kalit kompilyatorga manifest metadata jadvallarini o'z ichiga olmaydigan PE fayl ishlab chiqarishni aytadi. Ishlab chiqarilgan PE fayl har doim DLL PE fayli bo'ladi va bu fayl CLR undan foydalanishdan oldin assemblyga qo'shilishi kerak. /t:module kalitini ishlatganingizda, C# kompilyatori standart holda chiqish faylini .netmodule kengaytmasi bilan nomlaydi.
Visual Studio IDE da Assemblylarni Loyihaga Qo'shish
Agar siz loyihangizni qurish uchun Visual Studio IDE dan foydalansangiz, loyihangizga havola qilmoqchi bo'lgan assemblylarni qo'shishingiz kerak. Buning uchun Solution Explorer da havola qo'shmoqchi bo'lgan loyihani o'ng tugma bilan bosing, so'ngra Add Reference menyu elementini tanlang. Bu Reference Manager dialog oynasini ochadi.
Loyihangiz assemblyga havola qilishi uchun ro'yxatdan kerakli assemblyni tanlang. Agar kerakli assembly ro'yxatda bo'lmasa, Browse tugmasini bosib assemblyga (manifest o'z ichiga olgan faylga) yo'l ko'rsating. Solution opsiyasi joriy loyihadan bir xil solution dagi boshqa loyiha tomonidan yaratilgan assemblyga havola qilish imkonini beradi. COM opsiyasi boshqarilmaydigan COM serveriga boshqariladigan proksi-klass orqali kirishga ruxsat beradi. Browse opsiyasi yaqinda boshqa loyihaga qo'shilgan assemblyni tanlash imkonini beradi.
Assembly Linker (AL.exe) dan Foydalanish
C# kompilyatori o'rniga, Assembly Linker yordamchisi — AL.exe — yordamida assemblylar yaratishni xohlashingiz mumkin. Assembly Linker, agar siz turli kompilyatorlar yordamida qurilgan modullardan iborat assembly yaratmoqchi bo'lsangiz (kompilyatoringiz C# ning /addmodule ekvivalentini qo'llab-quvvatlamasa) yoki assembly paketlash talablaringizni qurilish vaqtida bilmasangiz foydali. AL.exe dan lokalizatsiya maqsadlarida foydalaniladigan faqat resursli assemblylar (satellite assemblylar) qurish uchun ham foydalanishingiz mumkin.
AL.exe yordamchisi faqat boshqa modullardagi turlarni tavsiflovchi manifest o'z ichiga olgan EXE yoki DLL PE fayl ishlab chiqarishi mumkin. MultiFileLibrary.dll assemblyni AL.exe yordamida qanday qurilishini tushunish uchun, keling ko'rib chiqaylik:
csc /t:module RUT.cs
csc /t:module FUT.cs
al /out:MultiFileLibrary.dll /t:library FUT.netmodule RUT.netmodule
Bu misolda ikkita alohida modul yaratiladi — RUT.netmodule va FUT.netmodule. Keyin uchinchi fayl — MultiFileLibrary.dll — ishlab chiqariladi. Bu kichik DLL PE fayl (/t[arget]:library kaliti tufayli) bo'lib, IL kodini o'z ichiga olmaydi, lekin RUT.netmodule va FUT.netmodule assembly qismidagi fayllar ekanligini ko'rsatuvchi manifest metadata jadvallariga ega. Natijadagi assembly uchta fayldan iborat: MultiFileLibrary.dll, RUT.netmodule va FUT.netmodule.
Visual Studio IDE ko'p faylli assemblylarni yaratish qobiliyatini qo'llab-quvvatlamaydi. Agar siz ko'p faylli assemblylar yaratmoqchi bo'lsangiz, buyruq qatori vositalarini ishlatishingiz kerak.
Assemblyga Resurs Fayllarini Qo'shish
AL.exe dan foydalanib assembly yaratganingizda, /embed[resource] kaliti yordamida assemblyga resurs sifatida fayl qo'shishingiz mumkin. Bu kalit istalgan faylni oladi va uning tarkibini natija PE fayliga joylashtiradi. Manifestning ManifestResourceDef jadvali resurslarning mavjudligini aks ettirish uchun yangilanadi.
AL.exe shuningdek /link[resource] kalitini qo'llab-quvvatlaydi. Bu kalit ham resurslarni o'z ichiga olgan faylni oladi. Biroq, /link[resource] kaliti manifestning ManifestResourceDef va FileDef jadvallarini yangilaydi — resurs faylining mavjudligini va assembly fayllarining qaysi birida ekanligini ko'rsatadi. Resurs fayli PE fayliga joylashtirilmaydi; u alohida qoladi va assemblyning boshqa fayllari bilan birga paketlanishi va deploy qilinishi kerak.
AL.exe singari, CSC.exe ham resurslarni kompilyator tomonidan yaratilgan assemblyga birlashtirish imkonini beradi. C# kompilyatorining /resource kaliti ko'rsatilgan resurs faylini natijadagi assembly PE fayliga joylashtiradi. Kompilyatorning /linkresource kaliti esa mustaqil resurs fayliga havola qilish uchun ManifestResourceDef va FileDef manifest jadvallariga yozuv qo'shadi.
Resurslar haqida oxirgi eslatma: standart Win32 resurslarini assemblyga joylashtirish mumkin. Buni AL.exe yoki CSC.exe dan foydalanganingizda /win32res kaliti yordamida .res faylining yo'lini belgilab amalga oshirishingiz mumkin. Bundan tashqari, /win32icon kaliti yordamida .ico faylining yo'lini belgilab, standart Win32 ikonka resursini osongina joylashtirish mumkin.
Boshqariladigan assembly fayllari ularda Win32 manifest resurs ma'lumotlarini ham o'z ichiga oladi. Standart holda, C# kompilyatori ushbu manifest ma'lumotlarini avtomatik ravishda ishlab chiqaradi, lekin /nowin32manifest kaliti bilan buni to'xtatishingiz mumkin.
Assembly Versiya Resurs Ma'lumotlari
AL.exe yoki CSC.exe PE faylli assembly ishlab chiqarganda, u PE faylga standart Win32 versiya resursini ham joylashtiradi. Foydalanuvchilar bu resursni faylning xususiyatlarini ko'rish orqali tekshirishlari mumkin. Ilova kodi shuningdek System.Diagnostics.FileVersionInfo ning statik GetVersionInfo metodini assembly yo'li bilan chaqirib bu ma'lumotni olishi va tekshirishi mumkin.
Assembly qurayotganingizda, versiya resurs maydonlarini manba kodingizda assembly darajasida qo'llaniladigan maxsus atributlar yordamida belgilashingiz kerak. Mana 2-4 rasmdagi versiya ma'lumotlarini ishlab chiqargan kod qanday ko'rinishda:
using System.Reflection;
// FileDescription versiya ma'lumoti:
[assembly: AssemblyTitle("MultiFileLibrary.dll")]
// Comments versiya ma'lumoti:
[assembly: AssemblyDescription("This assembly contains MultiFileLibrary's types")]
// CompanyName versiya ma'lumoti:
[assembly: AssemblyCompany("Wintellect")]
// ProductName versiya ma'lumoti:
[assembly: AssemblyProduct("Wintellect (R) MultiFileLibrary's Type Library")]
// LegalCopyright versiya ma'lumoti:
[assembly: AssemblyCopyright("Copyright (c) Wintellect 2013")]
// LegalTrademarks versiya ma'lumoti:
[assembly: AssemblyTrademark("MultiFileLibrary is a registered trademark of Wintellect")]
// AssemblyVersion versiya ma'lumoti:
[assembly: AssemblyVersion("3.0.0.0")]
// FILEVERSION/FileVersion versiya ma'lumoti:
[assembly: AssemblyFileVersion("1.0.0.0")]
// PRODUCTVERSION/ProductVersion versiya ma'lumoti:
[assembly: AssemblyInformationalVersion("2.0.0.0")]
// Language maydonini belgilash ("Culture" bo'limida muhokama qilinadi)
[assembly: AssemblyCulture("")]
Visual Studio da yangi C# loyihasi yaratganingizda, Properties papkasida AssemblyInfo.cs fayli avtomatik ravishda yaratiladi. Bu fayl ushbu bo'limda tavsiflangan barcha assembly versiya atributlarini va 3-bobda ko'rib chiqiladigan bir nechta qo'shimcha atributlarni o'z ichiga oladi.
2-4 jadval versiya resurs maydonlari va ularga mos keluvchi maxsus atributlarni ko'rsatadi. Agar siz assemblyni qurish uchun AL.exe dan foydalansangiz, maxsus atributlar o'rniga buyruq qatori kalitlari yordamida bu ma'lumotlarni belgilashingiz mumkin. E'tibor bering, C# kompilyatori bu buyruq qatori kalitlarini taklif qilmaydi va umumiy holda maxsus atributlardan foydalanish afzalroq usuldir.
| Versiya resursi | AL.exe kaliti | Maxsus atribut/Izoh |
|---|---|---|
| FILEVERSION | /fileversion |
System.Reflection.AssemblyFileVersionAttribute |
| PRODUCTVERSION | /productversion |
System.Reflection.AssemblyInformationalVersionAttribute |
| FILETYPE | /target |
/target:exe yoki /target:library ga qarab belgilanadi |
| AssemblyVersion | /version |
System.Reflection.AssemblyVersionAttribute |
| Comments | /description |
System.Reflection.AssemblyDescriptionAttribute |
| CompanyName | /company |
System.Reflection.AssemblyCompanyAttribute |
| FileDescription | /title |
System.Reflection.AssemblyTitleAttribute |
| FileVersion | /version |
System.Reflection.AssemblyFileVersionAttribute |
| LegalCopyright | /copyright |
System.Reflection.AssemblyCopyrightAttribute |
| LegalTrademarks | /trademark |
System.Reflection.AssemblyTrademarkAttribute |
| ProductName | /product |
System.Reflection.AssemblyProductAttribute |
Versiya Raqamlari
Oldingi bo'limda siz assemblyga bir nechta versiya raqamlari qo'llanilishi mumkinligini ko'rdingiz. Bu versiya raqamlarining barchasi bir xil formatga ega: nuqta bilan ajratilgan to'rtta qismdan iborat.
| Major Number | Minor Number | Build Number | Revision Number | |
|---|---|---|---|---|
| Misol: | 2 | 5 | 719 | 2 |
2-5 jadval versiya raqamining misolini ko'rsatadi: 2.5.719.2. Birinchi ikkita raqam versiyaning jamoatchilik idrokini tashkil qiladi. Jamoatchilik bu misolni assembly ning 2.5 versiyasi deb biladi. Uchinchi raqam — 719 — assembly qurilishini ko'rsatadi. Oxirgi raqam — 2 — qurilishning qayta ko'rib chiqilishini ko'rsatadi.
Assembly da uchta versiya raqami bog'langanligi juda afsuslantiradi va ko'p chalkashlikka olib keladi. Keling, har bir versiya raqamining maqsadini va qanday ishlatilishini tushuntiraman:
- AssemblyFileVersion — bu versiya raqami Win32 versiya resursida saqlanadi. Bu raqam faqat ma'lumot maqsadlari uchun; CLR bu versiya raqamini hech qanday tarzda tekshirmaydi. Odatda, siz ko'rsatmoqchi bo'lgan versiyaning ommaviy qismini ifodalash uchun major va minor qismlarni belgilaysiz. Keyin har bir qurilishda build va revision qismlarini oshirasiz. Bu versiya raqami Windows Explorer da ko'rinadi va odatda mijozning mashinasida muammo bartaraf etishda assemblyning ma'lum bir versiyasini aniqlash uchun ishlatiladi.
- AssemblyInformationalVersion — bu versiya raqami ham Win32 versiya resursida saqlanadi va yana faqat ma'lumot maqsadlari uchun; CLR uni tekshirmaydi. Bu versiya raqami assemblyni o'z ichiga olgan mahsulotning versiyasini ko'rsatish uchun mavjud. Masalan, mahsulotning 2.0 versiyasi bir nechta assemblylarni o'z ichiga olishi mumkin; bu assemblylarning biri 1.0 versiyasi deb belgilanishi mumkin, chunki u oldingi versiyada mavjud bo'lmagan yangi assembly.
- AssemblyVersion — bu versiya raqami AssemblyDef manifest metadata jadvalida saqlanadi. CLR bu raqamni kuchli nomlangan assemblylarga bog'lanishda ishlatadi (3-bobda muhokama qilinadi). Bu raqam juda muhim va assemblyni yagona identifikatsiya qilish uchun ishlatiladi. Assemblyni ishlab chiqishni boshlayotganingizda, major, minor, build va revision raqamlarini belgilashingiz kerak va assemblyning keyingi deploy qilinadigan versiyasi ustida ishlashga tayyor bo'lguningizcha ularni o'zgartirmasligingiz kerak.
Madaniyat (Culture)
Versiya raqamlari singari, assemblylar ham o'z identifikatsiyasining bir qismi sifatida madaniyatga ega. Masalan, nemischa uchun bitta assembly, shveytsariyacha nemischa uchun boshqa assembly va hokazo bo'lishi mumkin. Madaniyatlar birlamchi va ikkinchi darajali teglarni o'z ichiga olgan qator orqali aniqlanadi (RFC 1766 da tasvirlangan).
| Birlamchi teg | Ikkinchi darajali teg | Madaniyat |
|---|---|---|
| De | (yo'q) | Nemischa |
| De | AT | Avstriya nemischasi |
| De | CH | Shveytsariya nemischasi |
| En | (yo'q) | Inglizcha |
| En | GB | Britaniya inglizchasi |
| En | US | AQSh inglizchasi |
Umuman olganda, agar siz kod o'z ichiga olgan assembly yaratayotgan bo'lsangiz, unga madaniyat tayinlamaysiz. Bu assembly kodida odatda madaniyatga xos taxminlar bo'lmasligi sababli shunday. Madaniyat tayinlanmagan assembly madaniyatga neytral (culture neutral) deb ataladi.
Agar siz madaniyatga xos resurslari bo'lgan ilova loyihalayotgan bo'lsangiz, Microsoft sizga kodingiz va ilovangiz standart (fallback) resurslarini o'z ichiga olgan bitta assembly yaratishni tavsiya qiladi. Bu assemblyni qurayotganingizda, madaniyat belgilamang. Bu assembly boshqa assemblylar tur yaratish va manipulyatsiya qilishda havola qiladigan assembly bo'ladi.
Keyin faqat madaniyatga xos resurslarni o'z ichiga olgan — kodi umuman bo'lmagan — bir yoki bir nechta alohida assemblylar yaratishingiz mumkin. Madaniyat bilan belgilangan assemblylar satellite assemblylar deb ataladi. Bu satellite assemblylarga resurslar madaniyatini to'g'ri aks ettiruvchi madaniyat tayinlang. Siz qo'llab-quvvatlashni rejalashtirayotgan har bir madaniyat uchun bitta satellite assembly yaratishingiz kerak.
Satellite assemblyni deploy qilganingizda, uni ilovangiz bazaviy papkasining madaniyat matniga mos nomdagi quyi papkasiga joylashtirishingiz kerak. Masalan, agar ilova bazaviy papkasi C:\MyApp bo'lsa, AQSh ingliz tilidagi satellite assembly C:\MyApp\en-US quyi papkasiga joylashtirilishi kerak. Ish vaqtida satellite assembly resurslariga System.Resources.ResourceManager klassi yordamida kirish mumkin.
Oddiy Ilova Deploy Qilish (Shaxsiy Deploy Qilingan Assemblylar)
Ushbu bob davomida men modullarni qanday qurish va bu modullarni assemblyga qanday birlashtirish haqida tushuntirdim. Endi barcha assemblylarni paketlash va deploy qilish haqida gapirish vaqti keldi.
Windows Store ilovalarining assemblylarni paketlash bo'yicha juda qat'iy qoidalari bor va Visual Studio ilova talab qiladigan barcha assemblylarni bitta .appx fayliga paketlaydi. Bu fayl Windows Store ga yuklanadi yoki mashina ustiga o'rnatiladi.
Desktop (Windows Store bo'lmagan) ilovalar uchun assemblylar maxsus paketlash talab qilmaydi. Assembly to'plamini paketlashning eng oson usuli — shunchaki barcha fayllarni ko'chirishdir. Masalan, barcha assembly fayllarini CD-ROM ga joylab foydalanuvchining qattiq diskidagi papkaga nusxalaydigan oddiy o'rnatish dasturi yordamida foydalanuvchiga yetkazishingiz mumkin.
Assemblylar bog'liq assembly havola va turlari haqidagi barcha ma'lumotlarni o'z ichiga olganligi sababli, foydalanuvchi shunchaki ilovani ishga tushirishi mumkin va runtime havolalar qilingan assemblylarni ilovaning papkasida qidiradi. Ilovani o'rnatishdan chiqarish uchun registrni o'zgartirish shart emas — faqat barcha fayllarni o'chirsangiz kifoya!
Oddiy batch fayl yoki boshqa "o'rnatish dasturi" yordamida ilovani foydalanuvchining mashinasiga o'rnatish mumkin; biroq, ish stoli yorliqlari, Start menyu va boshqalarni yaratish uchun ko'proq murakkab o'rnatish dasturi kerak bo'ladi.
Albatta, Visual Studio da loyiha xususiyatlarini ko'rsatib Publish tabini bosish orqali ilovani nashr etishning o'rnatilgan mexanizmi mavjud. Siz Publish tabdagi opsiyalarni MSI fayl ishlab chiqarish va uni veb-sayt, FTP server yoki fayl yo'liga nusxalash uchun ishlatishingiz mumkin. MSI fayl shuningdek .NET Framework kabi zaruriy komponentlarni avtomatik o'rnatishi mumkin. Nihoyat, ilova ClickOnce texnologiyasi yordamida yangilanishlarni avtomatik tekshirishi va o'rnatishi mumkin.
Ilova bilan bitta papkaga deploy qilingan assemblylar shaxsiy deploy qilingan assemblylar (privately deployed assemblies) deb ataladi, chunki assembly fayllari boshqa ilovalar bilan bo'lishmaydi. Shaxsiy deploy qilingan assemblylar dasturchilar, oxirgi foydalanuvchilar va administratorlar uchun katta yutuq, chunki ularni shunchaki ilovaning bazaviy papkasiga nusxalash va bajariladigan kodni ishlatish kifoya. Bundan tashqari, ilovani shunchaki papkasidagi assemblylarni o'chirib o'rnatishdan chiqarish mumkin.
Bu oddiy o'rnatish/ko'chirish/o'rnatishdan chiqarish stsenariysi mumkin, chunki har bir assembly o'z ichida qaysi havolalangan assemblylar yuklanishi kerakligini ko'rsatuvchi metadataga ega; registr sozlamalari talab qilinmaydi. Bundan tashqari, havolalar assembly har bir turni doiralab oladi. Bu ilovaning har doim u qurilgan va sinov o'tkazilgan turning aynan o'sha turiga bog'lanishini anglatadi; CLR faqat bir xil nomga ega bo'lgan boshqa turni taqdim etuvchi boshqa assemblyni yuklay olmaydi. Bu COM dan farq qiladi, bu yerda turlar registrga yoziladi va ularni mashinadagi istalgan ilova tomonidan foydalanish mumkin.
Oddiy Administrativ Boshqarish (Konfiguratsiya)
Foydalanuvchi yoki administrator ilovaning bajarilish ba'zi jihatlarini eng yaxshi aniqlashi mumkin. Masalan, administrator assembly fayllarini foydalanuvchining qattiq diskida ko'chirishga yoki assembly manifestidagi ma'lumotlarni bekor qilishga qaror qilishi mumkin.
Ilova ustidan administrativ nazoratga ruxsat berish uchun ilova papkasiga konfiguratsiya fayli joylashtirilishi mumkin. Ilovaning nashriyotchisi bu faylni yaratishi va paketlashi mumkin. O'rnatish dasturi bu konfiguratsiya faylini ilovaning bazaviy papkasiga o'rnatadi. Bundan tashqari, mashinaning administratori yoki oxirgi foydalanuvchisi bu faylni yaratishi yoki o'zgartirishi mumkin. CLR assembly fayllarini topish va yuklash siyosatlarini o'zgartirish uchun bu faylning tarkibini talqin qiladi.
Bu konfiguratsiya fayllari Extensible Markup Language (XML) ni o'z ichiga oladi va ilova yoki mashina bilan bog'lanishi mumkin. Alohida fayl ishlatish (registr sozlamalariga nisbatan) faylni osongina zaxiralash va administratorga ilovani boshqa mashinaga nusxalash imkonini beradi — faqat kerakli fayllarni nusxalasangiz, administrativ siyosat ham ko'chiriladi.
Masalan, ilova nashriyotchisi MultiFileLibrary assembly fayllarini ilovaning assembly faylidan boshqa papkaga deploy qilishni xohlaydi deylik. Kerakli papka tuzilishi:
AppDir papkasi (ilova assembly fayllari):
Program.exe
Program.exe.config (quyida muhokama qilinadi)
AuxFiles quyi papkasi (MultiFileLibrary assembly fayllari):
MultiFileLibrary.dll
FUT.netmodule
RUT.netmodule
MultiFileLibrary fayllari ilovaning bazaviy papkasida emas bo'lganligi sababli, CLR ularni topishi va yuklashi mumkin bo'lmaydi; ilovani ishga tushirish System.IO.FileNotFoundException istisnosini keltirib chiqaradi. Buni hal qilish uchun, nashriyotchi XML konfiguratsiya faylini yaratadi va uni ilovaning bazaviy papkasiga deploy qiladi. Bu faylning nomi ilovaning asosiy assembly faylining nomi bo'lib, .config kengaytmasi qo'shiladi: Program.exe.config. Konfiguratsiya fayli quyidagicha ko'rinadi:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="AuxFiles" />
</assemblyBinding>
</runtime>
</configuration>
CLR assembly faylini topishga uringanida, har doim avval ilovaning papkasiga qaraydi va agar faylni u yerda topa olmasa, AuxFiles quyi papkasiga qaraydi. Siz probing elementining privatePath atributida nuqtali vergul bilan ajratilgan bir nechta yo'llarni belgilashingiz mumkin. Har bir yo'l ilova bazaviy papkasiga nisbatan hisoblanadi.
CLR assemblyni topishi kerak bo'lganda, u bir nechta quyi papkalarni ko'rib chiqadi. Quyida madaniyatga neytral assembly uchun qidirish tartibi ko'rsatilgan (firstPrivatePath va secondPrivatePath konfiguratsiya faylining privatePath atributi orqali belgilanadi):
AppDir\AsmName.dll
AppDir\AsmName\AsmName.dll
AppDir\firstPrivatePath\AsmName.dll
AppDir\firstPrivatePath\AsmName\AsmName.dll
AppDir\secondPrivatePath\AsmName.dll
AppDir\secondPrivatePath\AsmName\AsmName.dll
...
Agar assembly yuqoridagi papkalarning hech birida topilmasa, CLR .dll kengaytmasi o'rniga .exe kengaytmasi bilan qayta qidirishni boshlaydi. Agar assembly hali ham topilmasa, FileNotFoundException xatosi yuzaga keladi.
Satellite assemblylar uchun ham xuddi shunday qoidalar qo'llaniladi, faqat assembly ilovaning bazaviy papkasining madaniyatga mos nomdagi quyi papkasida bo'lishi kutiladi.
Bu XML konfiguratsiya faylining nomi va joylashuvi ilova turiga qarab farq qiladi:
- Bajariladigan ilovalar (EXE) uchun — konfiguratsiya fayli ilovaning bazaviy papkasida bo'lishi kerak va EXE faylining nomi bilan birga ".config" qo'shilgan bo'lishi kerak.
- Microsoft ASP.NET Web Form ilovalari uchun — fayl Web ilovaning virtual ildiz papkasida bo'lishi kerak va har doim Web.config deb nomlanadi.
Machine.config fayli ham mavjud bo'lib, u mashinaga o'rnatilgan barcha ilovalar uchun standart sozlamalarni belgilaydi. .NET Framework o'rnatilganda, u har bir CLR versiyasi uchun bitta Machine.config faylini yaratadi. Machine.config fayli quyidagi papkada joylashgan:
%SystemRoot%\Microsoft.NET\Framework\version\CONFIG
Machine.config faylidagi sozlamalar mashinadagi barcha ishlaydigan ilovalar uchun standart sozlamalarni ifodalaydi. Administrator bitta Machine.config faylini o'zgartirib mashinaning butun siyosatini yaratishi mumkin. Biroq, administratorlar va foydalanuvchilar bu faylni o'zgartirishdan saqlanishlari kerak, chunki u turli narsalarga tegishli ko'plab sozlamalarni o'z ichiga oladi. Bundan tashqari, siz ilovaning sozlamalarini zaxiralash va tiklash imkonini xohlaysiz — bu esa ilova-ga xos konfiguratsiya faylida sozlamalarni saqlash orqali amalga oshiriladi.