17

I'm developing a desktop application, and this application requires some information to run, but it doesn't change any of this information (the data must be loaded on every execution of the app, but the data is never changed). The data must be stored on the same computer as the app is running (client-side storage?).

It is also better if the user can't easily change this information (assume that they don't have much IT knowledge).

How should I storage this kind of information? A local database? XML that is sent with the application?

I'm using WPF.

appa yip yip
  • 425
  • 6
  • 17
  • 2
    This is not a meta. A meta is a site to discuss problems or concerns about the main sites where questions are asked. – jpmc26 Jul 20 '16 at 18:19
  • @jpmc26 oooh, I see. How can I call this? – appa yip yip Jul 20 '16 at 18:35
  • It's just an SE site. (Most people would just say "site"; the fact you're on an SE site is usually context enough.) – jpmc26 Jul 20 '16 at 19:20
  • 1
    Why don't you want the users to change the information? Is that a *security* concern or what? Is this information supposed to be kept secret from the user? The reasons could vastly change what answers are appropriate. – jpmc26 Jul 20 '16 at 19:22
  • 1
    @jpmc26 Well, it's *kind of* a security concern, but it's not a big deal. The main objective of the application is to communicate through a serial port with a temperature controller (like [this](http://pimg.tradeindia.com/01451127/b/2/Yudian-Make-Temperature-Controller.jpg) one), and the XML will store some information about the memory addresses of the controller. If the user alters it, it may cause problems during execution, so I would like to avoid it. But it's just a concern, like I said, not a big deal. p.s.: edited the question to replace *meta* for *SE*. Thanks. – appa yip yip Jul 20 '16 at 19:51
  • 2
    If you want a local database, take a look at SQLite. (But if the data is small enough to load into RAM on startup, I prefer a simple structured file like json or something binary) – CodesInChaos Jul 21 '16 at 07:34
  • 1
    "If the user alters it, it may cause problems during execution, so I would like to avoid it." doesn't sound like a security concern at all. A security concern is one where you have a passphrase or similar in the file. Just put the settings in an XML file next to the executable, and put a comment at the top that says "Don't touch the settings in this file!!". If the user's editing random files in your install directory, then they deserve whatever brokenness they get. – Roger Lipscombe Jul 21 '16 at 12:58

4 Answers4

21

If the data never changes and is read only, then just put it in a code file as a list of constants.

public readonly string AppStartUpData = "MyAppNeedsThis";

If this data is different per deployment, then an external file is fine.

.Net comes with built in .config files (App.Config). One should use those as there are standard ways (built in to the framework) to read the information from them.

Use the configuration files in case a setting needs to change (never say never) as they are just text files (Xml). If there is sensitive information one can encrypt a setting if needed.

Jon Raynor
  • 10,905
  • 29
  • 47
  • I thought about the constants/readonlys, the problem is that there's a **lot** of data, so I guess I'll follow up with the external file. Thank you! – appa yip yip Jul 20 '16 at 14:41
  • 6
    @schmaedeck ... so? You can put those definitions in a separate file and import that one. In fact I believe Qt does this kind of things when compilking forms and stuff so you end up with automatically generated files that have megabytes of binary data (e.g. images) in some constants, but if it is in a separate file there's nothing wrong with that. – Bakuriu Jul 20 '16 at 20:15
15

You can always add a file into your project and set its build type to Embedded Resource so that it is embedded directly into the application itself.

Alternatively a file that is encrypted and placed in an accessible location.

TheLethalCoder
  • 431
  • 2
  • 5
  • 10
  • 1
    This is the best answer. I would like to see some more guidance for how to achieve it. You get the benefits of a _potentially_ alterable configuration file but get to keep it static as it is embedded in your assembly. – Gusdor Jul 21 '16 at 09:45
14

A binary file would be the obvious answer, but it depends on how you are loading it - you might as well make life easy for yourself if you can.

XML might be a good choice as there are built in methods in C# for reading this. You could add a checksum to your data, so that if the user alters it, the checksum will no longer match (you need to add a check to make sure the checksum is valid)

A local db might create more problems because you have other dependencies you need to be able to access it

Matt Wilko
  • 372
  • 1
  • 8
  • I haven't thought about the checksum, it is a really nice idea. So I generate a checksum and store it on my application, so every time I unserialize the XML, I generate a new checksum and compare it with the first one? – appa yip yip Jul 20 '16 at 14:34
  • 4
    If you store the checksum in the application, you will never allow for a different configuration, so you may as well store the configuration data as application constants in your code. If you want to be able to change the configuration in the future, add the checksum (a better term would be a "hash") as a field of the XML, and use it to verify the XML has not been tampered with. Of course, a determined attacker could research your code, find your hash logic and use it to produce valid XML files, but anyway client-side applications are always vulnerable to determined attackers. – SJuan76 Jul 20 '16 at 20:37
  • 4
    Instead of file or local db, resource file embedded in assembly would be better. Hidden from end user, easily manageable by developer yet still power-user friendly. If performance is a concern, then binary serialization would be superior. – PTwr Jul 20 '16 at 20:46
  • @SJuan76 Yeah, the problem of hash on XML is that it can be changed if someone unserialize it. Anyway, **if** the XML change (which I think it's not gonna happen, but who knows) it will only change on a new version of the app, so guess I'll stick with the hash on code. – appa yip yip Jul 20 '16 at 22:19
  • @PTwr I'll take a look at the possibility of using a resource file. Is it embedded when compiling or when deploying? – appa yip yip Jul 20 '16 at 22:21
  • 2
    @schmaedeck: Resource files are literally files inside the executable binary. Icons and strings and whatever other constant data your program needs. – Mooing Duck Jul 20 '16 at 23:08
6

If you don't want the user to even peek at the data, you should serialize it into a binary data file.

Only the app would know the length of the chunks to read from it.

I don't know C# but in Java you would create the file like this:

FileOutputStream fos = new FileOutputStream(file);      
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(var1);
oos.writeObject(var2);
oos.writeObject(var3);
oos.writeObject(var4);

...and them read it like this:

FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
Object o[] = new Object[4];
o[0] = ois.readObject();
o[1] = ois.readObject();
o[2] = ois.readObject();
o[3] = ois.readObject();
Tulains Córdova
  • 39,201
  • 12
  • 97
  • 154