Grafikus C# – Windows Forms tanfolyam › 14.2 lecke Windows Forms · 14.2 lecke · build Lefordítottad a programot Release módban, és a EXE, DLL, projekt- és kimeneti mappák
bin\Release mappában egy tucat fájlt látsz. Melyik a program, melyik csak segédfájl, és mit kell átmásolnod egy másik gépre, hogy ott is fusson? Ha nem érted, mi micsoda, vagy túl keveset másolsz (a program nem indul), vagy mindent odaadsz, beleértve a fejlesztői fájlokat is. Ebben a leckében megismered a solution és a projekt felépítését, az EXE és a DLL szerepét, a kimeneti mappa fájljait (.deps.json, .runtimeconfig.json, .pdb, nyelvi almappák), azt, hogyan kerülnek az adatfájlok a kimenetbe, és hogyan ellenőrzöd tiszta gépen, hogy a programod önállóan működik.
A lecke végére
- elmagyarázod a solution (.sln), a projekt (.csproj) és az assembly fogalmát;
- megkülönbözteted az EXE és a DLL szerepét;
- tudod, mire való a kimeneti mappa minden fájlja;
- eldöntöd, mit kell átadni a felhasználónak, és mit nem;
- az adatfájlokat (kép, sablon, beállítás) beállítod, hogy a kimenetbe másolódjanak;
- tiszta gépen (vagy mappában) ellenőrzöd, hogy a program önállóan fut.
Mielőtt elkezded
Ehhez a leckéhez a 14.1 lecke (Debug és Release) és a 12.9 lecke (solution, több projekt) szükséges.
Solution, projekt, assembly
Konyvtar\ ← a solution mappa
Konyvtar.sln ← solution: a projektek gyűjteménye
Konyvtar.Core\ ← osztálykönyvtár projekt
Konyvtar.Core.csproj ← projektfájl: beállítások, hivatkozások
Models\, Services\ ... ← forráskódok (.cs)
Konyvtar.App\ ← Windows Forms projekt
Konyvtar.App.csproj
Form1.cs, Form1.Designer.cs, Program.cs
bin\, obj\ ← generált: fordítás eredménye (nem a forrás!)| Fogalom | Mi ez? |
|---|---|
Solution (.sln) | Egy vagy több projekt gyűjteménye (12.9 lecke): a Visual Studio ezt nyitja meg. |
Projekt (.csproj) | Egy fordítási egység: a forrásfájlok, a hivatkozások és a build-beállítások (14.1 lecke). |
| Assembly | A fordítás eredménye: egy .exe vagy .dll fájl, amely a lefordított kódot (köztes nyelven, IL) és az adatait tartalmazza. Egy projekt = egy assembly. |
.cs, .csproj, .resx): ezt tartod verziókezelésben (Git). A bin és obj mappa generált: bármikor újraépíthető, ezért nem tárolod (.gitignore)..dll fájlját a Forms kimeneti mappájába másolja: így a program mellett ott lesz a szükséges könyvtár.EXE és DLL
| EXE (futtatható) | DLL (könyvtár) | |
|---|---|---|
| Szerep | A program belépési pontja (Main); indítható. | Kódkönyvtár; nem indítható, más program tölti be. |
| Projekt típusa | Windows Forms App (OutputType: WinExe), Konzolalkalmazás (Exe). | Class Library (osztálykönyvtár). |
| Példa | Konyvtar.App.exe | Konyvtar.Core.dll, System.Text.Json.dll, Microsoft.Data.Sqlite.dll |
| Újrahasználat | Nem hivatkozható (általában). | Több program is használhatja ugyanazt a DLL-t. |
Program.exe egy kicsi indítóprogram (apphost), amely elindítja a futtatókörnyezetet, és betölti a valódi kódot tartalmazó Program.dll-t. Ezért található a mappában egyszerre Program.exe és Program.dll. Mindkettő kell.Jósolj!
A felhasználónak csak a Konyvtar.App.exe fájlt másolod át, a mappa többi fájlját nem. Mi történik indításkor?
Jóslat ellenőrzése
A program nem indul: hiányzik a Konyvtar.App.dll (a valódi kód), a .runtimeconfig.json (melyik futtatókörnyezet kell) és a Konyvtar.Core.dll. Hibaüzenet: „A fájl nem található” vagy „FileNotFoundException: Could not load file or assembly...”. Az egész kimeneti mappát (a PDB nélkül) át kell adni, vagy a közzétételt (publish, 14.5 lecke) kell használni.
A kimeneti mappa fájljai
| Fájl | Mi ez? | Átadni? |
|---|---|---|
Program.exe | Az indítóprogram (apphost). | Igen |
Program.dll | A program lefordított kódja. | Igen |
Program.runtimeconfig.json | Melyik .NET futtatókörnyezet és verzió kell a futtatáshoz. | Igen |
Program.deps.json | A függőségek listája (milyen DLL-eket tölt be). | Igen |
Konyvtar.Core.dll, *.dll (NuGet) | A hivatkozott könyvtárak. | Igen |
hu\, de\ ... mappák | Nyelvi erőforrások (satellite assemblies) a könyvtárakhoz. | Igen (ha használt a program) |
Program.pdb | Hibakereső szimbólumok. | Nem kell (tartsd meg magadnak a hibakereséshez) |
*.xml (dokumentáció) | Fejlesztői dokumentáció. | Nem |
Adatfájlok (kép, sablon, .json beállítás) | A programod által használt fájlok, ha a kimenetbe másoltad (lásd lent). | Igen |
bin\Release\net8.0-windows mappa tartalma, a .pdb fájlok nélkül. A rendezettebb mód a Publish (14.5 lecke), amely pontosan a szükséges fájlokat gyűjti össze..runtimeconfig.json megmondja, milyen .NET kell (például Microsoft.WindowsDesktop.App 8.0). Ha a gépen nincs telepítve, a program nem indul: a 14.3 lecke ezt tárgyalja.Jósolj!
A felhasználó mappájából kitörlöd a Program.pdb fájlt. Elindul-e a program?
Jóslat ellenőrzése
Igen, a PDB a futáshoz nem szükséges: csak a hibakereséshez és a stack trace sorszámaihoz kell. Ezért nem kell átadnod a felhasználónak (és meg kell őrizned a saját archívumodban, hogy a hibajelentéseket értelmezni tudd).
Adatfájlok a kimenetben
<ItemGroup>
<!-- a kép a fordításkor a kimeneti mappába másolódik (mindig, vagy csak ha újabb) -->
<None Update="Kepek\logo.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Sablonok\*.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>// ROSSZ: a munkakönyvtár (Environment.CurrentDirectory) attól függ, HOGYAN indították a programot
string ut = Path.Combine(Environment.CurrentDirectory, "Kepek", "logo.png");
// JÓ: a program SAJÁT mappája (az exe helye)
string ut2 = Path.Combine(AppContext.BaseDirectory, "Kepek", "logo.png");
if (File.Exists(ut2)) { pbLogo.Image = Image.FromFile(ut2); } // és try–catch (13.6 lecke)Environment.CurrentDirectory a program indításának helye (parancsikon, parancssor, Fájl megnyitása ablak is módosíthatja!). A saját fájljaidhoz az AppContext.BaseDirectory megbízható.Resources.resx, 9. fejezet): az exe tartalmazza, nincs külön fájl, nincs hiányzó fájl. Kis ikonoknál és képeknél kényelmes.ApplicationData mappába kerülnek; a program mappája csak olvasható adatoknak való.Jósolj!
A program a Kepek\logo.png fájlt a munkakönyvtárból tölti. A fejlesztő gépen a Visual Studióból fut (jó), a felhasználó viszont egy parancsikonról indítja, amelynek munkakönyvtára az Asztal. Mit tapasztal?
Jóslat ellenőrzése
A program a Desktop\Kepek\logo.png fájlt keresi: nem találja (FileNotFoundException vagy üres kép). Az AppContext.BaseDirectory a program mappáját adja, függetlenül az indítás módjától.
Mit tegyél ide: a Release kimeneti mappa fájljai, és a tulajdonságablak a Copy to Output Directory beállítással.Javasolt fájlnév: winforms-14-2-kimenet.webp · Alt szöveg: A kimeneti mappa fájljai
Hibakeresés: te vagy a hibadetektív
Mi a baj, és hogyan javítod?
Gondold végig az okot, és csak utána nyisd le a megoldást.
1. A másik gépen nem indul, nincs hibaüzenet
Csak az exe-t másoltad át. Hiányzik a Ok és javítás
.dll és a .runtimeconfig.json. Add át a teljes kimeneti mappát (PDB nélkül), vagy használd a Publish-t (14.5 lecke).
2. FileNotFoundException: Could not load file or assembly
Egy könyvtár hiányzik a másik gépen. A hivatkozott DLL nem másolódott át (vagy nem kerül a kimenetbe). Ellenőrizd a kimeneti mappa DLL-jeit, és a Ok és javítás
.deps.json függőségeit; NuGet csomagnál 14.4 lecke.
3. A kép nem jelenik meg a másik gépen
A fejlesztő gépen megjelenik, a felhasználónál üres. Nem kerül a kimenetbe (nincs Copy to Output Directory), vagy a munkakönyvtárból töltöd. Állítsd be a másolást, és használd az Ok és javítás
AppContext.BaseDirectory-t.
4. A bin mappában régi fájlok vannak
Egy már törölt DLL még ott van, és a program használja. Clean és Rebuild (14.1 lecke); átadás előtt tiszta mappából fordíts.Ok és javítás
5. A program mappájába nem lehet írni
Telepítés után mentéskor A program a saját (Program Files) mappájába ír. A felhasználói adatot az UnauthorizedAccessException.Ok és javítás
ApplicationData mappába tedd (13.6 lecke).
6. Az átadott mappa óriási
Több száz MB-ot kell másolni. Debug kimenetet, PDB-ket, vagy önálló (self-contained) közzétételt adtál át. Release, PDB nélkül; a közzétételi módot a 14.5 lecke tárgyalja.Ok és javítás
Mini projekt: kimeneti mappa vizsgálata és tiszta gépes próba
Készíts egy kis programot, amely önmagáról megmondja, hol fut, mely fájlok vannak mellette, és mely DLL-eket töltötte be; majd próbáld ki másik mappában (ideális esetben másik gépen):
- Solution:
Vizsgalo.slnkét projekttel:Vizsgalo.Core(osztálykönyvtár, egyInfoosztállyal) ésVizsgalo.App(Windows Forms, hivatkozik a Core-ra). - Adatfájlok: az App projektben legyen
Kepek\logo.pngésSablonok\udvozlet.txt; állítsd mindkettőre a Copy to Output Directory: Copy if newer beállítást. - Felület:
lblHely(a program mappája),lstFajlok(a mappa fájljai),lstDll(betöltött assembly-k),pbLogo,txtSablon,lblUzenet. - Kód: másold be a lenti megoldás kódját (az
AppContext.BaseDirectoryhasználatával, hibakezeléssel). - Release fordítás:
dotnet build -c Releasevagy a Visual Studióból; nézd meg abin\Releasemappát, és sorold fel a fájlokat a leckében látott táblázat szerint (átadandó / nem). - Átmásolás: másold az átadandó fájlokat (a
.pdbnélkül) egy új, üres mappába (példáulC:\Teszt\Vizsgalo), és indítsd onnan. - Hibatesztek: (a) hagyd ki a
Vizsgalo.Core.dllfájlt; (b) hagyd ki a.runtimeconfig.jsonfájlt; (c) hagyd ki aKepekmappát; (d) indítsd parancsikonról más munkakönyvtárral. Írd le mindegyik hibát (üzenet, ok). - Tiszta gép: ha van rá lehetőséged, másold át egy másik számítógépre (vagy virtuális gépre), amelyen nincs fejlesztői környezet; jegyezd fel, mi hiányzik (a 14.3 lecke a .NET futtatókörnyezetről szól).
- Jegyzék: készíts átadási jegyzéket (táblázat): fájl, szerep, átadni?, mi történik, ha hiányzik.
Megoldás megnyitása (próbáld ki előbb önállóan!)
private void Form1_Load(object sender, EventArgs e)
{
string mappa = AppContext.BaseDirectory; // a program saját mappája, nem a munkakönyvtár
lblHely.Text = "Program mappa: " + mappa + Environment.NewLine + "Munkakönyvtár: " + Environment.CurrentDirectory;
try
{
foreach (string f in Directory.GetFiles(mappa).OrderBy(x => x)) { lstFajlok.Items.Add(Path.GetFileName(f) + " (" + new FileInfo(f).Length / 1024 + " KB)"); }
}
catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException) { lblUzenet.Text = "A mappa nem olvasható: " + ex.Message; }
foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies().OrderBy(x => x.GetName().Name))
{
lstDll.Items.Add(a.GetName().Name + " " + a.GetName().Version);
}
lblUzenet.Text = "Core.Info: " + Vizsgalo.Core.Info.Uzenet(); // a Core.dll tényleges használata
string kep = Path.Combine(mappa, "Kepek", "logo.png");
string sablon = Path.Combine(mappa, "Sablonok", "udvozlet.txt");
try { using (Image tmp = Image.FromFile(kep)) { pbLogo.Image = new Bitmap(tmp); } } // a fájl nem marad zárolva
catch (Exception ex) when (ex is IOException || ex is ArgumentException || ex is OutOfMemoryException) { lblUzenet.Text += " | Kép: " + ex.Message; }
try { txtSablon.Text = File.ReadAllText(sablon); }
catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException) { txtSablon.Text = "(a sablon nem található: " + Path.GetFileName(sablon) + ")"; }
}
// ---- Vizsgalo.Core/Info.cs ----
namespace Vizsgalo.Core
{
public static class Info { public static string Uzenet() { return "a Core.dll betöltődött (" + typeof(Info).Assembly.GetName().Version + ")"; } }
}Várt tapasztalat: a hiányzó Core.dll miatt „Could not load file or assembly 'Vizsgalo.Core'” (a program a betöltéskor leáll); a hiányzó .runtimeconfig.json miatt az exe nem indul (futtatókörnyezet-hiba); a hiányzó Kepek mappa miatt a kód elkapja a hibát, és az üzenetsorban jelzi; a parancsikon eltérő munkakönyvtára a BaseDirectory miatt nem okoz hibát. A pontos hibaszövegek a Windows és a .NET verziótól függenek: jegyezd fel a sajátjaidat.
Mit tegyél ide: a kész vizsgáló program (mappák, fájlok, betöltött DLL-ek) és az átadási jegyzék.Javasolt fájlnév: winforms-14-2-kesz.webp · Alt szöveg: A kimeneti mappa vizsgáló program
Három önálló gyakorlófeladat
Egyszerre csak egyet csinálj: tervezd meg, írd meg, futtasd, ellenőrizd, és csak utána nyisd ki a megoldást.
1. Saját átadási jegyzék
Készíts átadási jegyzéket egy korábbi projektedhez a Release kimenet fájljaiból. Táblázat: fájl, szerep (indító, kód, konfiguráció, függőség, erőforrás, szimbólum), átadni-e, a hiányának következménye. A Egy lehetséges megoldás
.pdb és a dokumentációs .xml nem kerül át.
2. Beágyazott erőforrás
Tedd a Project → Properties → Resources → kép hozzáadása; logo.png képet beágyazott erőforrásba (Resources.resx), és töltsd be onnan. Mi az előny?Egy lehetséges megoldás
Properties.Resources.logo. Előny: nincs külön fájl, amelyet el lehetne veszíteni; hátrány: a kép cseréjéhez újrafordítás kell.
3. Függőség-ellenőrzés
Nézd meg a A fájl .deps.json fájlt, és sorold fel, milyen külső könyvtárakat használ a programod.Egy lehetséges megoldás
libraries szekciója felsorolja a NuGet csomagokat és projekthivatkozásokat verzióval; mindegyiknek ott kell lennie a kimeneti mappában DLL-ként (vagy a keretrendszer része).
Gyakorlótár: 6 további feladat
Három szinten gyakorolhatsz: alap, közepes és kihívás. Csak a próbálkozás után nyisd le a megoldást.
Alap szint
1. EXE vagy DLL?
Melyik indítható: az Az .exe vagy a .dll?Megoldás megnyitása
.exe; a .dll kódkönyvtár, amelyet más program tölt be.
2. Mi a solution?
Fogalmazd meg egy mondatban. Egy vagy több projekt gyűjteménye (Megoldás megnyitása
.sln), amelyet a Visual Studio egyben nyit meg.
Közepes szint
3. A .pdb
Átadod-e a felhasználónak? Miért tartsd meg mégis? Nem kell átadni; magadnak tartsd meg, mert a hibajelentések stack trace-ének sorszámaihoz és a hibakereséshez kell.Megoldás megnyitása
4. runtimeconfig.json
Mire való? Megmondja, milyen .NET futtatókörnyezet és verzió kell a program futtatásához.Megoldás megnyitása
Kihívás szint
5. BaseDirectory
Miért jobb az Mindig a program mappáját adja, míg a munkakönyvtár az indítás módjától függ (parancsikon, parancssor, fájlválasztó ablak).AppContext.BaseDirectory a munkakönyvtárnál?Megoldás megnyitása
6. Írható adat
Hová mentse a program a felhasználó adatait telepítés után? Az Megoldás megnyitása
ApplicationData (vagy LocalApplicationData) mappába; a program mappájába (Program Files) általában nincs írási jog.
Gyors önellenőrzés
Válaszolj fejben, és csak utána nyisd le a választ. A fordítás eredménye: egy Az exe az indító (apphost), a dll tartalmazza a program kódját. A függőségek listája. A fájl a fordításkor a kimeneti mappába másolódik. A A program saját mappáját. Tiszta mappában vagy másik gépen, fejlesztői környezet nélkül.1. Mi az assembly?
.exe vagy .dll.2. Miért van .exe és .dll is?
3. Mi a .deps.json?
4. Mi a Copy to Output Directory?
5. Mit nem adsz át?
.pdb és a dokumentációs .xml fájlokat.6. Mit ad az AppContext.BaseDirectory?
7. Hol ellenőrzöd az önállóságot?
Mit tudsz már?
- Érted a solution, projekt és assembly viszonyát, valamint az EXE és DLL szerepét.
- Tudod, mi micsoda a kimeneti mappában, és mit kell átadni.
- Az adatfájlokat a kimenetbe másolod, és a program mappájából éred el.
- Tiszta környezetben ellenőrzöd, hogy a program önállóan fut.
Következő lecke: .NET és .NET Framework futtatókörnyezet
Milyen .NET kell a program futtatásához, és mit tegyél, ha a felhasználó gépén nincs.



