App.config szerelvénybetöltési hiba egyedi sectiont használva
2021-08-02T16:49:31+02:00
2021-08-07T14:26:35+02:00
2022-08-12T03:55:38+02:00
Mordai
Sziasztok!
Az alábbi, remélhetőleg egyszerűen megoldható problémával fordulok hozzátok:
Az egyik WinForm (VS2019, C#) alkalmazásomban létrehoztam az App.config-ban egy saját szekciót (Section, nem SectionGroup), mellé természetesen saját osztályt is, hogy "OOP" tudjam az adatokat kezelni. A szekció neve LicenseData, melynek az osztálya a LicenseData.cs fájlban található:
Az egyszerűség kedvéért a program neve, ill. a névtartomány legyen ProgramNeve.

namespace ProgramNeve { class LicenseData : ConfigurationSection { [ConfigurationProperty("License", IsRequired = true)] public License LicenseInfo { get { return LicenseInfo; } set { LicenseInfo = value; } } public class License : ConfigurationElement { ... egyéb property-k (mint LicenseKey és FullName stb) ... }
Ennek megfelelően az App.config-ot módosítva:

<configuration> <configSections> <section name="LicenseData" type="ProgramNeve.LicenseData, ProgramNeve" /> </configSections> ... <LicenseData> <License LicenseKey="Valamikulcs" FullName="Teszt Elek"></License> </LicenseData> </configuration>
A legújabb leírás alapján a szekció típusánál a type értéket az alábbiak szerint kell beállítani: <AssemblyNeve>.<HanszáltOsztályVagyRef>, <AssemblyNeve>.
Ennek ugyan megfelel a config fájlom, ám a kért LicenseData lekérdezésekor fatális hibába ütközik a program:

FileNotFoundException: A(z) „ProgramNeve” fájl vagy szerelvény, illetve annak egyik függősége nem tölthető be.
Mintha nem tudná, hogy a saját namespace-ben keresse a LicenseData.cs-t, vagy én nem tudom... Sok StackOverflow kérdést, bejegyzést is olvastam, de nem találtam megoldást. Volt akinél elírás miatt keletkezett a hiba, volt, aki nem a megfelelő formulát használta, és kihagyta az <AssemlbyNeve> részt a vessző után, de én mindent jól írtam, hogyha minden igaz.
StackOverflow bejegyzés ugyan erről a hibáról

Van aki esetleg ugyan így járt, vagy lenne valamiféle ötlete a megoldással kapcsolatban?
Nagyon szépen köszönöm mindenkinek!
Mutasd a teljes hozzászólást!
Helló,

alapvetően jó irányba mentél, de nekem úgy tűnik, jó sok boilerplate kell, hogy ez így működjön.

Összedobtam egy működő megoldást, de nem győzöm hangsúlyozni, hogy ez elég legacy terület, speciális esetekben célszerű csak ezt használni.

Évtizedek óta van beépített settings kezelés, az jóval egyszerűbb és rugalmasabb is
(project -> jobb click -> properties -> Settings), pl. lehetséges egyből a user profile könyvtárában tárolni a beállításokat, nem a program mellett, így egy másik user más beállításokat használhat.
Mutasd a teljes hozzászólást!
Csatolt állomány

  • Szia!

    Először is, nagyon szépen köszönöm a kis projektet, amit összedobtál! Sokkal praktikusabb megoldások vannak benne, mint amit én használtam.

    Alapvetően azért nem használom a Settings "részleget", mert ez szenzitívebb adat, amit jó helyen szeretnék tárolni. A Settingsbe könnyeben beleturkálhatnak, ha az ember járt már az AppData/Local mappában ugyebár... Az App.config pedig ha jól tudom, magába az assembly-ben van eltárolva [ProgramNeve.exe], legalábbis nekem a Debug könyvtárba nem löki ki külön .config fájlként (le is van tiltva - "Do Not Copy"), és saját, de nem szekciós egyedi adatokkal teljesen jól működik:

    <appSettings> <add key="product_Id" value="66" /> </appSettings>
    Itt minden gond nélkül tudom a product_Id kulcsot kiolvasni, átírogatni stb...

    (Ha esetleg van jobb, praktikusabb megoldás arra, hogy szenzitív adatokat hol tároljak, nagyon szívesen várom az ötleteket, egyelőre ezt találtam egy jó megoldásnak )

    A Solution-ödben viszont buildelődött egy .dll fájl is, ami nálam viszont nincs. Nem tudom milyen projekttípust választottál vagy készítettél, én sima WinForm Application-t csinálok. Lehetséges, hogy ezt hiányolja valamiért? De akkor meg a sima appSettings miért működik?
    Mutasd a teljes hozzászólást!
  • A beépített Settings-ben scope-ként beállíthatod, hogy user vagy application szintű legyen a megosztás. Ha application szintet választasz, mindenkinek ugyanaz lesz, pont úgy, mint a fenti esetben. Ha user-t, akkor megy a profil könyvtárba (AppData...).

    Ha szenzitív adatot tárolnál az meg megint egy másik történet, aminek az eddigiekhez nincs köze. Tetszőlegesen titkosíthatsz egy kívánt section-t az app.config-ban, ami így védve lesz, de ez működik a beépített Settings-zel is. Readme, itt találsz példakódot is (desktop vagy konzol app-ban is így működik).

    A projecttípus .NET 5 Windows Forms.

    Az App.config pedig ha jól tudom, magába az assembly-ben van eltárolva

    Az egy egyszerű xml file, ami az .exe-d mellé kerül ugyanazzal a névvel. Ha nem véded le az adott section-t a fenti módon, azt bárki láthatja, átírhatja, ha joga van hozzá.
    Mutasd a teljes hozzászólást!
  • A beépíttet Settingsben jó lenne a Scope mint Application, csak azzal meg az a baj, hogy read only, itt meg fontos lenne, hogy át lehessen írni "via code".

    Esetleg ha hagyom ezt az App.config-os megoldást, hol a fenébe máshol tudom tárolni az ilyesféle adatokat, hogy biztos helyen legyenek? (Nyilván aki ügyes megtalálja, de legalább egy minimális védelme legyen neki.)
    Mutasd a teljes hozzászólást!
  • Mutasd a teljes hozzászólást!
  • Esetleg ha hagyom ezt az App.config-os megoldást, hol a fenébe máshol tudom tárolni az ilyesféle adatokat, hogy biztos helyen legyenek? (Nyilván aki ügyes megtalálja, de legalább egy minimális védelme legyen neki.)

    Szia

    Ha Te telepíted személyesen, akkor @papa Readme linkjén találod a megoldást. Készítesz egy induló képernyőt, ahol beírod a titkos kulcsot, és Mentés. Readme-ben a minta.

    Ha Windows Domain policy telepíti mehet ugyan ez emberi beavatkozás nélkül.

    Egyéb esetre egy talán egy licence webapi szerver időbélyeges tokennel.
    Mutasd a teljes hozzászólást!
  • A beépíttet Settingsben jó lenne a Scope mint Application, csak azzal meg az a baj, hogy read only.

    MSDN:
    The crucial distinction between application-scope and user-scope settings is that user-scope settings are read/write at run time, and their values can be changed and saved in code. Application-scope settings are read only at run time. While they can be read, they cannot be written to.
    Mutasd a teljes hozzászólást!
  • Hmmm, ezt nem tudtam, köszi.

    Igazából meg kéne fogalmaznod a követelményrendszert, akkor talán könnyebb lenne segíteni. Pontosan milyen szituációban, mit akarsz vagy mit nem akarsz elérni?

    Azt látnod kell, hogy olyan eset nincs, hogy deployolsz egy titkot (pl. connection string vagy license key) egy gépre, azt az app tudja használni, de a user ne lássa. Az eltitkosítás is alapvetően abban segíthet, hogy másik user ne tudja azt használni. De teljesen hozzáférhetetlenné tenni egy titkot helyi gépen nem lehet. A biztos megoldás, ha azt szerver oldalon tárolod.
    Mutasd a teljes hozzászólást!
  • Alapvetően egy egyszerű licencelési megoldást szerettem volna megcsinálni az alkalmazáshoz, aminek a részeként miután a felhasználó megadta a megfelelő "termékkulcsot" a program eltárolja azt, és esetenként ránéz, hogy még jó-e, aktív-e, nem tiltott-e a kulcs stb stb...

    Ezt most jelenleg egy WordPress + Woocommerce szerelemgyermek és egy ehhez írt Software Licensing pluginnal oldottam meg, amit természetesen nem a tökéletes megvalósítás, de kisüzemű fejlesztésekhez jónak láttam. Az aktiválás maga REST API-n keresztül történik, tehát ahogy írtad is, minden fontos adat a szerveren van tárolva, a program csak lekéri ezeket, amikor valaki egy termékkulcsot aktiválni szeretne (jó-e egyáltalán a kulcs, aktiválható-e még stb...).

    Az API használatához azonban még mindig szükségesek szenzitív információk, customer key, secret key, amik nélkül ugyebár az API sem ér sokat. Például ezeket a kulcsokat is valahol, valahonnan elő kéne tudni szedni, amikor az API használatra kerül. Ezeket sem igazán tudom, hogy hol kéne eltárolni, már ha egyáltalán "elszabad".
    Mutasd a teljes hozzászólást!
    Csatolt állomány
  • Köszi, így már érthetőbb.

    Ha ez egy átlagos program, amit csak védeni szeretnél, én nem bonyolítanám nagyon túl.

    Kliens oldalon első bejelentkezésnél megadja a user a termékkulcsot, azt nyugodtan mentheted a settings-be, esetleg titkosítással, hogy más ne tudja kinyerni. Az API statikus kulcsait nem kéne a kliensen tárolni, és más szenzitív adatot sem.

    Bejelentkezéskor bekérsz felhasználónevet/jelszót, ill. ha ennyire nem kritikus az alkalmazási terület, akár magát az elmentett kulcsot is felhasználhatod az azonosításra. Authorizációra többféle megoldás van, statikus API kulcson kívül. Az ipari standard a JWT-token használata: készítesz egy végpontot, amely egy valid kulcs megadásával ad egy n ideig érvényes tokent, és azt használod fel API authorizációra. Ezt a végpontot aztán adott esetben bármilyen kliensről tudod használni, nemcsak a Forms app-odról (web, telefon app stb.). A token idővel lejár, és ha el is lopják, más nem tudja majd idővel felhasználni (ellentétben egy statikus API kulccsal, amit feltehetően most használsz).

    Ha még ennél is egyszerűbb megoldás is elegendő, akár magát a termékkulcsot is felhasználhatod API-kulcsnak egy custom authorizációval.

    Mindezek a pontos alkalmazási területtől függenek, hiszen pl. egy banki app-nál ennél szigorúbb megoldásra van szükség, de egy tipikus egyszerűbb esetben a fenti elegendő, hogy csak valid kulccsal tudják használni az adott programot.
    Mutasd a teljes hozzászólást!
  • Rendben, köszönöm szépen a hasznos tanácsokat!
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd