Grafikus C# – Windows Forms tanfolyam › 14.7 lecke

Windows Forms · 14.7 lecke · kiadás

Fájlok, adatbázisok helye telepítés után

Fejlesztés közben minden fájl „ott van, ahol a program”: a bin mappában. Telepítés után ez megváltozik: a program a Program Files mappába kerül, ahová a felhasználó nem írhat; a beállítások, a mentett adatok, az adatbázis és a naplók másik helyre valók. Aki ezt nem tervezi meg, annak a programja a saját gépén működik, a felhasználónál viszont „Access denied” hibával áll le, vagy a felhasználó adatai eltűnnek frissítéskor. Ebben a leckében megtanulod, melyik adat hová való (ApplicationData, LocalApplicationData, MyDocuments, ProgramData), hogyan kezeld a beállításokat (Settings és saját JSON), hol legyen az SQLite adatbázis és hogyan frissítsd a sémáját, mi az első indítás és a hordozható mód, és hogyan kezeld a jogosultsági hibákat.

  • kb. 100 perc
  • közepes–haladó szint
  • adatok helye
Diák C# programozást gyakorol egy tanulósarokban

A lecke végére

  • eldöntöd, hogy melyik adat hová való (program mappa, ApplicationData, LocalApplicationData, MyDocuments, ProgramData);
  • az elérési utakat egy központi osztályban kezeled;
  • beállításokat mentesz és töltesz (Settings és JSON), alapértékekkel és verzióval;
  • az SQLite adatbázist a megfelelő helyre teszed, és a sémáját verziózod (user_version);
  • kezeled az első indítást és a hordozható módot;
  • kezeled a jogosultsági hibákat, és megmutatod a felhasználónak, hol vannak az adatai.

Mielőtt elkezded

Ehhez a leckéhez a 13.6 lecke (fájl- és adatbázis-kivételek), a 14.2 lecke (AppContext.BaseDirectory) és a 14.6 lecke (telepítés, eltávolítás) szükséges.

14.6 Telepítési csomagok →

Hová melyik adat való?

HelyTipikus útvonalMire való?
Program mappa
AppContext.BaseDirectory
C:\Program Files\Program\Csak olvasható: a program, alapértelmezett sablonok, képek. Ide nem írunk.
ApplicationData (roaming)C:\Users\Név\AppData\Roaming\A felhasználó beállításai és adatai, amelyeknek „követniük” kell (vállalati hálózaton a felhasználóval együtt vándorol).
LocalApplicationDataC:\Users\Név\AppData\Local\Gépfüggő, nagyobb adatok: adatbázis, gyorsítótár, naplók.
MyDocumentsC:\Users\Név\Documents\A felhasználó saját fájljai: exportok, dokumentumok, amelyeket ő keres és kezel.
CommonApplicationDataC:\ProgramData\Minden felhasználó közös adata; az írási jog a mappától függ (telepítéskor kell beállítani).
Temp%TEMP%Ideiglenes fájlok (Path.GetTempPath()): bármikor törölhetők.
Utak.csC#
public static class Utak
{
private const string Program = "Diaknyilvantarto";

// A hordozható mód: ha a program mellett van a "portable.txt", minden adat a program mappájában lesz (pendrive)
public static bool Hordozhato { get { return File.Exists(Path.Combine(AppContext.BaseDirectory, "portable.txt")); } }

private static string Gyoker(Environment.SpecialFolder mappa)
{
return Hordozhato ? Path.Combine(AppContext.BaseDirectory, "Adat") : Path.Combine(Environment.GetFolderPath(mappa), Program);
}

public static string BeallitasMappa { get { return Letrehoz(Gyoker(Environment.SpecialFolder.ApplicationData)); } }
public static string AdatMappa { get { return Letrehoz(Path.Combine(Gyoker(Environment.SpecialFolder.LocalApplicationData), "Adat")); } }
public static string NaploMappa { get { return Letrehoz(Path.Combine(Gyoker(Environment.SpecialFolder.LocalApplicationData), "Naplo")); } }
public static string ExportMappa { get { return Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); } }

public static string BeallitasFajl { get { return Path.Combine(BeallitasMappa, "beallitasok.json"); } }
public static string AdatbazisFajl { get { return Path.Combine(AdatMappa, "diakok.db"); } }

private static string Letrehoz(string ut) { Directory.CreateDirectory(ut); return ut; } // létrehozza, ha még nincs
}
Miért központi osztály?Az elérési utak egyetlen helyen élnek: nincs szétszórt "C:\\..." sztring, és a hordozható mód vagy a mappacsere egy helyen módosítható. A Form és a szolgáltatások az Utak.AdatbazisFajl értéket kérik, nem építenek útvonalat.
Roaming és LocalA Roaming (ApplicationData) a hálózati profilú gépeken a felhasználót követi: kicsi, fontos adatnak (beállítások) való. A Local (LocalApplicationData) a gépen marad: nagy adatnak (adatbázis, gyorsítótár, napló). Egyszerű otthoni gépen a kettő működésben nem különbözik, de a helyes választás a vállalati környezetben számít.
Dokumentumok: ami a felhasználóéAmit a felhasználó keres (exportált CSV, jelentés), a Dokumentumok mappába való, a programnév alatti almappával; a belső adat (adatbázis, napló) az AppData alatt marad: nem akarjuk, hogy a felhasználó ott véletlenül belenyúljon.
Írási jog a Program Files alattA normál felhasználó nem írhat a Program Files mappába (13.6, 14.6 lecke). A régi programok „működtek”, mert a Windows virtualizálta az írást (VirtualStore): rejtett másolatot készített; ez zavaros viselkedést okoz, ne támaszkodj rá.

Jósolj!

A program a naplo.txt fájlt a AppContext.BaseDirectory mappába írja. Fejlesztés közben (a bin mappában) működik. Mi történik telepítés után, a Program Files mappában, normál felhasználóval?

Jóslat ellenőrzése

UnauthorizedAccessException az első naplóíráskor (vagy, ha a naplózó elnyeli, nem lesz napló). A naplónak a LocalApplicationData mappába kell kerülnie. Ez a leggyakoribb „csak a saját gépemen működik” hiba telepítés után.

Beállítások: Settings vagy saját JSON

1. Properties.Settings (beépített)

Visual Studio: Project → Properties → Settings: nevet, típust, hatókört (User) és alapértéket adsz meg; a kód: Properties.Settings.Default.Nev, mentés: Settings.Default.Save(). A fájl (user.config) a %LocalAppData% alatt, verziónként külön mappában él.

2. Saját JSON fájl

Egy Beallitasok osztály, amelyet a System.Text.Json ment az ApplicationData mappába. Átlátható (a felhasználó vagy te megnyithatod), hordozható móddal is működik, és a verzióváltás nem „veszíti el” a beállításokat.

Beallitasok.cs (using System.Text.Json; using System.IO;)C#
public class Beallitasok
{
public int Verzio { get; set; } = 2; // a fájl sémájának verziója (migrációhoz)
public bool FrissitesEllenorzes { get; set; } = true; // alapérték: ha a fájlban nincs, ez lesz
public string Nyelv { get; set; } = "hu";
public int AblakSzel { get; set; } = 900;
public int AblakMag { get; set; } = 600;
public string UtolsoMappa { get; set; } = "";

public static Beallitasok Betolt()
{
try
{
if (!File.Exists(Utak.BeallitasFajl)) { return new Beallitasok(); } // első indítás: alapértékek

return JsonSerializer.Deserialize<Beallitasok>(File.ReadAllText(Utak.BeallitasFajl)) ?? new Beallitasok();
}
catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException || ex is JsonException)
{
return new Beallitasok(); // sérült fájl: alapértékekkel indulunk (és naplózunk), nem omlunk össze
}
}

public void Ment()
{
try
{
string tmp = Utak.BeallitasFajl + ".tmp";

File.WriteAllText(tmp, JsonSerializer.Serialize(this, new JsonSerializerOptions { WriteIndented = true }));
if (File.Exists(Utak.BeallitasFajl)) { File.Delete(Utak.BeallitasFajl); }
File.Move(tmp, Utak.BeallitasFajl); // biztonságos mentés (13.6 lecke)
}
catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException) { /* naplózd; a beállítás mentésének hibája ne állítsa le a programot */ }
}
}

// Form: indításkor betölt, zárásakor ment
private Beallitasok beallitasok;

private void Form1_Load(object s, EventArgs e) { beallitasok = Beallitasok.Betolt(); this.Size = new Size(beallitasok.AblakSzel, beallitasok.AblakMag); }
private void Form1_FormClosing(object s, FormClosingEventArgs e) { beallitasok.AblakSzel = this.Width; beallitasok.AblakMag = this.Height; beallitasok.Ment(); }
AlapértékekA tulajdonságok alapértéke (= true, = "hu") azért fontos, mert egy régebbi beállításfájlból az újabb verzió új beállításai hiányozhatnak: ilyenkor az alapérték marad, és nem lesz hibás (false/null) érték.
Verzió és migrációA Verzio mező megmondja, melyik séma szerint mentették: ha a program új beállításokat vezet be, betöltéskor a Verzio alapján átalakítja a régit (például a Nyelv mező átnevezése), majd növeli a verziót.
Settings: Upgrade()A Properties.Settings új programverziónál új mappát használ, ezért az új verzió „üres” beállításokkal indul. A megoldás: egy Upgrade jelző a beállításokban, és induláskor Settings.Default.Upgrade() hívás, ha az még igaz. A JSON-nál ez a gond nincs: a fájl verziófüggetlen.
Mit ne tároljJelszót, tokent ne tárolj szövegesen. Ha muszáj, az operációs rendszer védelmét használd (ProtectedData, DPAPI: felhasználóhoz kötött titkosítás), és a legkevesebbet tárold.

Jósolj!

Az 1.0-s program Properties.Settings beállításokat használt. A felhasználó frissít 1.1-re, és az összes beállítása visszaáll az alapértékre. Mi történt?

Jóslat ellenőrzése

A Settings a user.config fájlt verziónként külön mappában tárolja, ezért az 1.1 nem találja az 1.0 beállításait. Megoldás: induláskor Settings.Default.Upgrade() (egy „frissítve van-e” jelzővel), vagy a verziófüggetlen saját JSON fájl.

Az adatbázis helye és a séma verziója

Adatbazis.cs (using Microsoft.Data.Sqlite;)C#
public static class Adatbazis
{
private const int AktualisVerzio = 2; // a program által várt séma verziója

public static SqliteConnection Nyit()
{
SqliteConnection kap = new SqliteConnection("Data Source=" + Utak.AdatbazisFajl); // az AppData alatt, nem a program mappájában

kap.Open();

return kap;
}

// INDULÁSKOR: létrehozza vagy frissíti a sémát (migráció)
public static void Inicializal()
{
using (SqliteConnection kap = Nyit())
{
int verzio = Verzio(kap); // PRAGMA user_version: új adatbázisnál 0

using (SqliteTransaction tr = kap.BeginTransaction())
{
if (verzio < 1) { Futtat(kap, tr, "CREATE TABLE diak (id INTEGER PRIMARY KEY, nev TEXT NOT NULL)"); }
if (verzio < 2) { Futtat(kap, tr, "ALTER TABLE diak ADD COLUMN osztaly TEXT NOT NULL DEFAULT ''"); } // 2. verzió: új oszlop

Futtat(kap, tr, "PRAGMA user_version = " + AktualisVerzio);
tr.Commit();
}
}
}

private static int Verzio(SqliteConnection kap)
{
using (SqliteCommand c = kap.CreateCommand()) { c.CommandText = "PRAGMA user_version"; return Convert.ToInt32(c.ExecuteScalar()); }
}

private static void Futtat(SqliteConnection kap, SqliteTransaction tr, string sql)
{
using (SqliteCommand c = kap.CreateCommand()) { c.Transaction = tr; c.CommandText = sql; c.ExecuteNonQuery(); }
}

// BIZTONSÁGI MÁSOLAT migráció előtt
public static void Mentes()
{
if (File.Exists(Utak.AdatbazisFajl)) { File.Copy(Utak.AdatbazisFajl, Utak.AdatbazisFajl + ".bak", true); }
}
}
user_versionAz SQLite PRAGMA user_version egy egész szám az adatbázisban, amelyet te használhatsz a séma verziójának jelzésére. Új adatbázisnál 0. Induláskor összeveted a program által várt (AktualisVerzio) értékkel, és a hiányzó lépéseket sorban lefuttatod.
Migráció tranzakcióbanA séma módosításai egy tranzakcióban futnak (13.6 lecke): ha egy lépés hibás, az egész visszagörgetődik, és az adatbázis nem marad „félig frissítve”. A migráció előtt készíts biztonsági másolatot (.bak).
Frissítés a felhasználó adataivalA program új verziója ugyanazt az adatbázist találja, amelyet a régi létrehozott: a migráció viszi át. Ezért nem szabad a sémát „kézzel újraírni” (DROP TABLE): a felhasználó adatai elvesznének. Az új oszlopokhoz ALTER TABLE ... ADD COLUMN és alapérték.
Közös adatbázisHa több felhasználó ugyanazt az adatbázist használja (ProgramData), az írási jogot a telepítőnek kell beállítania, és az SQLite zárolási korlátai (egyszerre egy író) miatt egy szerver-adatbázis lehet jobb. Egyfelhasználós asztali programnál az AppData a megfelelő hely.

Jósolj!

Az 1.0 program az osztaly oszlop nélküli táblát hozta létre. A 1.1 program az új oszloppal számol, de nem migrál: CREATE TABLE IF NOT EXISTS mellett fut. Mi történik a frissített felhasználónál?

Jóslat ellenőrzése

A CREATE TABLE IF NOT EXISTS nem módosítja a már létező táblát: az osztaly oszlop hiányzik, és az első lekérdezés SqliteException (no such column) hibával elszáll. A friss telepítés (új adatbázis) jól működik, a frissített nem: ezt csak „régi adatbázissal” végzett teszt találja meg. A séma verziózott migrációja oldja meg.

Első indítás, hordozható mód, jogosultságok

Program.cs / Form1.cs (using System.Diagnostics;)C#
// INDULÁSKOR: a mappák, adatbázis és beállítások előkészítése
private void Elokeszit()
{
try
{
bool elsoIndulas = !File.Exists(Utak.AdatbazisFajl); // a mappákat az Utak már létrehozza

if (!elsoIndulas) { Adatbazis.Mentes(); } // migráció előtt másolat

Adatbazis.Inicializal();
beallitasok = Beallitasok.Betolt();

if (elsoIndulas) { tsslUzenet.Text = "Üdvözlünk! Az adataid itt vannak: " + Utak.AdatMappa; }
}
catch (Exception ex) when (ex is UnauthorizedAccessException || ex is IOException || ex is SqliteException)
{
MessageBox.Show("A program nem tudja létrehozni vagy megnyitni az adatait itt: " + Utak.AdatMappa + Environment.NewLine + ex.Message + Environment.NewLine + Environment.NewLine + "Ellenőrizd a mappa jogosultságait, vagy a lemezt.", "Adathiba", MessageBoxButtons.OK, MessageBoxIcon.Warning);
Application.Exit(); // adat nélkül nincs értelme tovább futni: kontrolláltan kilépünk
}
}

// MENÜ: Adatmappa megnyitása (a felhasználó lássa, hol vannak az adatai)
private void mnuAdatmappa_Click(object sender, EventArgs e)
{
Process.Start(new ProcessStartInfo(Utak.AdatMappa) { UseShellExecute = true }); // megnyitja a Fájlkezelőben
}
Első indításTelepítés után az adatmappa és az adatbázis még nincs meg: a programnak ezt létre kell hoznia (CreateDirectory, séma-létrehozás), alapértékekkel, és barátságosan köszönteni. Az első indítás tesztje: töröld az AppData mappát, és indítsd újra a programot.
Hordozható módA portable.txt fájl jelzi, hogy minden adatot a program melletti Adat mappába kell tenni (pendrive, 14.5 lecke ZIP). A mappának írhatónak kell lennie: ezért hordozható módban a program nem telepíthető a Program Files mappába.
Jogosultsági hiba kezeléseHa az adatmappa nem írható (házirend, hibás jogosultság, csak olvasható meghajtó), a program ne összeomoljon, hanem érthetően jelezze az útvonalat és az okot (13.6 lecke), és kontrolláltan lépjen ki, vagy ajánljon másik helyet.
Adatmappa a felhasználónakA Súgó → Adatmappa megnyitása menü megmutatja a felhasználónak, hol vannak az adatai (mentéshez, hibabejelentéshez, törléshez). A %AppData% mappa rejtett a Fájlkezelőben: a menü segít.

Jósolj!

A program portable.txt jelenlétében a program mappájába (Adat) ír, de a felhasználó a ZIP-et a Program Files alá csomagolta ki. Mi történik?

Jóslat ellenőrzése

A Program Files alatt a program mappája nem írható: az első adat-létrehozás UnauthorizedAccessException-nel leáll (hordozható módban az Utak létrehozni próbálja az Adat mappát). Megoldás: a README-ben jelezd, hogy a hordozható módot írható helyre (Asztal, pendrive, saját mappa) kell kicsomagolni, és a program adjon érthető hibaüzenetet.

📷 Képernyőkép helye

Mit tegyél ide: a Fájlkezelő a %AppData% és %LocalAppData% program-mappáival, és az „Adatmappa megnyitása” menü.Javasolt fájlnév: winforms-14-7-adatmappa.webp · Alt szöveg: A program adatmappái az AppData alatt

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. Access denied telepítés után

A program a saját mappájába ír.

Ok és javítás

Program Files alatt nincs írási jog. A beállítások az ApplicationData, az adatok és naplók a LocalApplicationData mappába kerüljenek (az Utak osztályon át).

2. A frissítés után eltűntek a beállítások

Az 1.1 verzió alapértékekkel indul.

Ok és javítás

Properties.Settings verziónkénti mappája: Settings.Default.Upgrade(), vagy verziófüggetlen JSON fájl.

3. A frissített felhasználónál no such column

A friss telepítés jó, a frissített nem.

Ok és javítás

Nincs séma-migráció (CREATE TABLE IF NOT EXISTS nem módosít). PRAGMA user_version és sorrendben lefuttatott ALTER TABLE lépések; teszteld régi adatbázissal.

4. A sérült beállításfájl miatt nem indul

A program JsonException-nel leáll.

Ok és javítás

A betöltés nem kezeli a sérült fájlt. try–catch, és alapértékekkel induljon (a sérült fájlról másolat, és naplózás).

5. A felhasználó nem találja az exportot

A program a rejtett AppData mappába exportált.

Ok és javítás

Amit a felhasználó keres, az a Dokumentumok mappába való (vagy Mentés másként ablak); és jelezd az útvonalat az üzenetben.

6. Két felhasználó adata összekeveredik

Egy közös gépen mindenki ugyanazt a beállítást látja.

Ok és javítás

A beállítások a ProgramData vagy a program mappa alá kerültek. Felhasználónkénti adat az ApplicationData/LocalApplicationData mappába való (minden felhasználónak saját).

Mini projekt: adatkezelés központi Utak osztállyal

Rendezd át egy meglévő programodat (például a 13.10 diáknyilvántartót) úgy, hogy telepítés után is helyesen működjön, és próbáld ki három helyzetben:

  1. Utak osztály: hozd létre az Utak osztályt (a leckéből), és cseréld le a programban az összes beégetett elérési utat (C:\..., AppContext.BaseDirectory írás, Environment.CurrentDirectory).
  2. Beállítások: készíts Beallitasok JSON osztályt (ablakméret, utolsó mappa, frissítés-ellenőrzés be/ki), alapértékekkel, sérült fájl kezelésével, biztonságos mentéssel.
  3. Adatbázis: az SQLite fájl az Utak.AdatbazisFajl alatt; Inicializal migrációval (user_version 1 → 2: új osztaly oszlop), biztonsági másolattal.
  4. Napló: a naplózó (13.7 lecke) a Utak.NaploMappa mappába ír.
  5. Export: a CSV-export a Dokumentumok mappába kerül (Utak.ExportMappa + almappa), az üzenet kiírja az útvonalat.
  6. Menü: Súgó → Adatmappa megnyitása és Beállítások mappa megnyitása (Process.Start).
  7. Első indítás próba: töröld az adatmappákat; indítsd a programot; az üdvözlő üzenet jelenjen meg, minden mappa és az adatbázis jöjjön létre.
  8. Migráció próba: készíts 1-es verziójú adatbázist (az osztaly oszlop nélkül, user_version = 1, néhány sorral); indítsd az új programot; ellenőrizd, hogy az oszlop megjelent, az adat megmaradt, a .bak létrejött, a user_version 2 lett.
  9. Jogosultsági próba: állítsd az adatmappát csak olvashatóra (Tulajdonságok → Csak olvasható, vagy a biztonsági fülön tiltsd az írást), és indítsd a programot: érthető hibaüzenet és kontrollált kilépés legyen, nem összeomlás.
  10. Hordozható mód: tegyél portable.txt fájlt a program mellé; az adatok a program Adat mappájában jelenjenek meg (írható helyen); jegyezd fel a viselkedést a README-be.
Megoldás megnyitása (próbáld ki előbb önállóan!)
Migrációs teszt: az 1-es verziójú adatbázis létrehozása (using Microsoft.Data.Sqlite;)C#
// Egy 1-es verziójú adatbázis előállítása a próbához (csak a teszthez: ezt futtasd, MIELŐTT az új program indul)
public static void RegiAdatbazis(string ut)
{
if (File.Exists(ut)) { File.Delete(ut); }

using (SqliteConnection kap = new SqliteConnection("Data Source=" + ut))
{
kap.Open();

string[] sql = {
"CREATE TABLE diak (id INTEGER PRIMARY KEY, nev TEXT NOT NULL)",
"INSERT INTO diak (nev) VALUES ('Anna'), ('Béla')",
"PRAGMA user_version = 1"
};

foreach (string s in sql)
{
using (SqliteCommand c = kap.CreateCommand()) { c.CommandText = s; c.ExecuteNonQuery(); }
}
}
}

// Ellenőrzés a migráció után (az új program indulása után)
using (SqliteConnection kap = Adatbazis.Nyit())
using (SqliteCommand c = kap.CreateCommand())
{
c.CommandText = "SELECT nev, osztaly FROM diak"; // az osztaly oszlop már létezik, alapértéke üres

using (SqliteDataReader r = c.ExecuteReader()) { while (r.Read()) { System.Diagnostics.Debug.WriteLine(r.GetString(0) + " / '" + r.GetString(1) + "'"); } }
}

Várt tapasztalat: az Anna és Béla sor megmarad, az osztaly mező üres (alapérték); a PRAGMA user_version 2; a diakok.db.bak létrejött. A csak olvasható mappánál a program az UnauthorizedAccessException-t elkapja, kiírja az útvonalat, és kilép. A pontos üzenetek a Windows nyelvétől és verziójától függnek.

📷 Képernyőkép helye

Mit tegyél ide: a program menüje az „Adatmappa megnyitása” pontokkal, és a migráció előtti-utáni adatbázis.Javasolt fájlnév: winforms-14-7-kesz.webp · Alt szöveg: A program adatmappái és a migráció eredménye

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. Adatok átvitele

A felhasználó új gépre költözik. Hogyan viheti át az adatait?

Egy lehetséges megoldás

Az adatmappa (vagy az adatbázis és a beállításfájl) másolása; még jobb egy beépített Biztonsági mentés / Visszaállítás menü (ZIP az adatmappából a Dokumentumok alá), amely ellenőrzi a verziót és a sérülést.

2. Settings Upgrade

Írd meg a Settings.Default.Upgrade() hívást úgy, hogy csak az első indításkor (új verziónál) fusson.

Egy lehetséges megoldás

A beállításokban egy bool UpgradeSzukseges (alapérték true); induláskor: if (Settings.Default.UpgradeSzukseges) { Settings.Default.Upgrade(); Settings.Default.UpgradeSzukseges = false; Settings.Default.Save(); }.

3. Titok tárolása

A program egy API-kulcsot tárol. Hol és hogyan?

Egy lehetséges megoldás

Lehetőleg ne tárold; ha kell, ProtectedData.Protect (DPAPI, DataProtectionScope.CurrentUser) titkosítva az ApplicationData mappában; a kulcsot a forráskódba és a verziókezelésbe ne tedd.

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. Hová mit?

Hová teszed: (a) a beállításokat; (b) az adatbázist; (c) az exportált CSV-t?

Megoldás megnyitása

(a) ApplicationData; (b) LocalApplicationData; (c) MyDocuments (a felhasználó mappája).

2. Írható-e?

Írhat-e a program a Program Files mappába normál felhasználóként?

Megoldás megnyitása

Nem: UnauthorizedAccessException; a felhasználói adatot máshová kell tenni.

Közepes szint

3. Roaming vagy local?

Mi a különbség?

Megoldás megnyitása

A roaming a felhasználóval vándorol hálózati profil esetén (kis, fontos adat); a local gépen marad (nagy adat, gyorsítótár).

4. Alapérték

Miért kell alapérték a beállításokban?

Megoldás megnyitása

Az újabb verzió új beállításai hiányozhatnak a régi fájlból; az alapérték helyes működést ad, nem null/false hibát.

Kihívás szint

5. Migráció

Miért nem elég a CREATE TABLE IF NOT EXISTS a frissítéshez?

Megoldás megnyitása

Nem módosítja a már létező táblát: az új oszlop nem jön létre. Verziózott migráció (user_version és ALTER TABLE) kell.

6. Teszt régi adattal

Hogyan teszteled, hogy a frissítés megőrzi a felhasználó adatait?

Megoldás megnyitása

Az előző verzióval létrehozott (vagy mentett) adatbázison és beállításfájlon futtatod az új programot, és ellenőrzöd az adatok, a séma és a verzió helyességét; a friss telepítés önmagában nem elég.

Gyors önellenőrzés

Válaszolj fejben, és csak utána nyisd le a választ.

1. Hová ír a program?

Az AppData mappákba, nem a program mappájába.

2. Mi az Utak osztály haszna?

Az elérési utak egy helyen élnek; a hordozható mód és a mappák cseréje egy helyen módosítható.

3. Mire jó a Verzio a beállításokban?

A fájl sémájának verziója: a migrációhoz.

4. Mit jelent a user_version?

Az SQLite adatbázis általad használt séma-verziószáma.

5. Mi az első indítás?

A mappák, az adatbázis és az alapbeállítások létrehozása, ha még nincsenek.

6. Hogyan kezeled a nem írható mappát?

Érthető hibaüzenettel és kontrollált kilépéssel (vagy másik hely felajánlásával), nem összeomlással.

7. Mi a hordozható mód?

A portable.txt jelzi, hogy az adatok a program melletti mappába kerülnek (írható helyen).

Mit tudsz már?

  • Eldöntöd, melyik adat hová kerül (program mappa, ApplicationData, LocalApplicationData, MyDocuments).
  • Központi Utak osztállyal kezeled az elérési utakat és a hordozható módot.
  • Beállításokat mentesz alapértékkel és verzióval, és adatbázist migrálsz user_version segítségével.
  • Kezeled az első indítást és a jogosultsági hibákat.

Következő lecke: Ikon, verzió, szerző és About

A program arculata és azonosítása: az ikon, a verziószám, a szerzői adatok és a Névjegy ablak.