Files
Rozpisky/Rozpisky/Data/Migrace.cs
T
marekandClaude Opus 5 3c0e30bf35 Uživatelská data do %APPDATA%\Rozpisky místo vedle .exe
Vše, co píše uživatel, míří přes novou třídu UzivatelskaData do profilu
uživatele: cad.json, layout.json, error.log, tisk_diag.log. Dosud se
zapisovalo vedle .exe, takže .exe v Program Files (složka jen pro čtení)
nebo přeinstalace novou verzí uživatele o data připravily.

Dodávané podklady (šablona, mustr, loga, mapovani.json) se dál čtou vedle
.exe – ty se naopak při každé instalaci obnovují. Hranice mezi tím, co se
instaluje, a tím, co patří uživateli, vede přesně tudy.

Portable režim zůstává: soubor portable.txt vedle .exe vrátí staré chování
(běh z USB, vývoj s jednou složkou).

Migrace: Migrace.PrenesStaraData() při startu přenese cad.json a layout.json
ze staré polohy, pokud v cíli ještě nejsou; originál označí příponou
.migrovano. Nic se nemaže a nic novějšího se nepřepíše.

Číselníky přijdou na řadu samostatně (rozpad na dodávanou a uživatelskou
vrstvu).

Build 0 chyb / 0 varování, 36 testů zelených.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 10:39:25 +02:00

61 lines
2.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.IO;
namespace Rozpisky.Data;
/// <summary>
/// Jednorázový přesun dat starších verzí, které zapisovaly vedle .exe, do uživatelské složky
/// (<see cref="UzivatelskaData"/>). Bez toho by uživatel po aktualizaci našel prázdné číselníky
/// a přenastavený CAD. Volá se jednou při startu, ještě než si na data sáhne kterýkoli store.
/// <para>
/// Zásada: nikdy nic nemazat a nikdy nepřepsat novější data. Soubor se přenese jen tehdy, když
/// v cíli ještě není; originál zůstane ležet jako <c>*.migrovano</c> (jediná kopie uživatelových dat).
/// Selhání nesmí shodit start horší než nepřenesená data je aplikace, která nenaběhne.
/// </para>
/// </summary>
public static class Migrace
{
/// <summary>Přípona, kterou dostane původní soubor po přenesení.</summary>
public const string PriponaHotovo = ".migrovano";
/// <summary>Přenese <c>cad.json</c> a <c>layout.json</c> ze složky aplikace do uživatelské.
/// Číselníky mají vlastní cestu (rozpad na vrstvy) viz <see cref="CiselnikyStore"/>.</summary>
public static void PrenesStaraData()
{
Prenes(CadEnginesStoreNazev);
Prenes(LayoutConfigStoreNazev);
}
private const string CadEnginesStoreNazev = "cad.json";
private const string LayoutConfigStoreNazev = "layout.json";
/// <summary>Přesune soubor ze složky aplikace do uživatelské, pokud tam ještě není.
/// V portable režimu jsou obě složky totožné a neudělá se nic.</summary>
private static void Prenes(string nazevSouboru)
{
try
{
var zdroj = Path.Combine(AppContext.BaseDirectory, nazevSouboru);
var cil = UzivatelskaData.Cesta(nazevSouboru);
if (string.Equals(zdroj, cil, StringComparison.OrdinalIgnoreCase)) return;
if (!File.Exists(zdroj) || File.Exists(cil)) return;
File.Copy(zdroj, cil);
OznacJakoPrenesene(zdroj);
}
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException)
{
// Nezapisovatelná instalační složka apod. data zůstanou tam, kde jsou, a zkusí se
// přenést zase příště. Start aplikace to zastavit nesmí.
}
}
/// <summary>Přejmenuje původní soubor na <c>*.migrovano</c>, aby se přenos neopakoval a aby
/// starší verze programu (kdyby ji uživatel vrátil) nezmátla už neaktuální data. Nedaří-li se
/// to (soubor jen pro čtení), nevadí kopie v cíli už existuje a další běh přenos přeskočí.</summary>
internal static void OznacJakoPrenesene(string cesta)
{
try { File.Move(cesta, cesta + PriponaHotovo, overwrite: true); }
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) { }
}
}