Recommended place for Windows Service state storage? - c#

I have a Windows Service written in C# (.Net 3.5) and I need to store some state somewhere so that next time the service starts up, it knows where it left off.
What is the recommended store for this type of thing? The registry? What if I just put some user settings in a Settings.settings file? Where would the user profile be for a service executing as LocalSystem or NetworkService?

Personally, I prefer the registry for server state storage, provided it isn't a large amount of information.
If you're storing a large amount of information, a local database is another option. Services have the advantage of running under elevated privelidges, so you can typically use local file storage, as well.

If it's a small, fairly simple chunk of data, you can create an XML serializable class and very easily write it to disk on shutdown and read it back on startup. For a simple enough class, you can just add the [Serializable] attribute, and the XmlSerializer will automatically know how to serialize/deserialize it.
If you have enough data that a SQL database would be a better fit, look into SQL Server Compact Edition or the System.Data.SQLite binding for SQLite.
Both will let you create a database as a single file, without having to install any extra Windows services or configure anything. System.Data.SQLite doesn't even need to be installed - it's contained entirely with the .dll that your project references.
In either case, the best location for the file is probably SpecialFolder.CommonApplicationData - I think this ends up being C:\ProgramData\ on Vista, but avoids having to hardcode the exact path.

I would go with a .settings file, since its properties are type safe. This is of course assuming that the service is not going to store a large amount of information. Does it really matter where the system chooses to store the settings file?

I hate to say this, but the best answer is that it depends. Without knowing the purpose of your service, a correct answer can't be given. Having said that... the world is your oyster, so to speak.

Related

Best approach for storing sensitive data without using a database or an .xml file

I'm developing an application in c# which uses an .xml file to obtain information that is used inside the logic of the app. When a new version of the app is launched, a setup is created (using Inno Setup Compiler) and after successfully installing the setup, the .xml is placed inside the setup files of the app. This .xml file contains about 200 objects with 4 properties each of sensitive data.
I got asked to launch a customer version of the app, and a requirement for this version is to remove the access or manipulation of this .xml file, since it contains sensitive data that the customer should not be able to see or manipulate.
My senior engineer told me to simply implement the information inside a list in the source code, so that the use of the .xml file is removed and the customer can't manipulate this info once installed the app, as it would be hidden inside the source code, but this seems really inefficient for me and i would need to change a lot of logic about the use of the .xml file inside the app for this to work.
Is there a way to create a setup of the app and hiding this file in the setup files so it cant be manipulated by the customer?
If there isn't, what approach could you suggest me to do? Or do i have no options but to do this the hard way?
If you want to make it harder for the end user to modify the information, while still keeping a separate configuration file that won't require code change of the application itself, you can sign the file and have the application verify the signature.
A simplest way is to to calculate a hash of a file and "secret" value. Of course it is hardly tamperproof. But in the end, there's no tamperproof way to prevent a user from manipulating data on his/hers own computer. It's only about how hard you want to make it.
A better way would be to use a proper certificate for the signature. The application will know only the public key and will use it to verify a signature created with a private key, which will never leave the development team.
From a theoretical standpoint, if your program can get hold of the data, then a user with full control of the computer on which the program is running can also get hold of the data if they try hard enough. That means you can make it difficult for them, but you can't make it impossible. So if that's what you're trying to achieve, you need to be quite clear about the limitations of the approach.
How difficult should you make it? Well, if it's purely a commercial risk, you should make it hard enough that the cost of getting the data is greater than the benefit. If the risk can't be measured in that way, for example if there are legal requirements for you to protect the data, then that isn't going to be good enough.
For some situations, it's probably enough to encrypt the XML file, and bury the decryption key deep within the logic of a compiled program written in a language that doesn't allow easy decompilation. That's likely to be better than simply burying the XML data within the compiled program, which is what your senior engineer is suggesting. But her suggestion may be OK too. It really shouldn't be too difficult to change the program logic from reading an external file to reading a string constant within the program.

Release build without config file

I'm trying to release a software I wrote to multiple Computers in several different locations. The Program itself is a Windows Forms Application. To install it I added a setup project which also works perfectly fine. All files get copied to the right folders and the choices the user can make during the installation work without a flaw. But:
The only problem is that the config file, which contains sensible data like for example the SQL connection string, gets also copied / installed on the target computer.
Is there a way to store this data unreadable for the user in the application?
I thought about just writing it in a class since the application gets obfuscated but I'm not sure if this is secure enough and if this really is a way to go...
Any help appreciated!
You might cryptographically secure the sensitive file with a private key embedded in code itself with an obfuscation scheme. This is better then embedding all sensitive config data in code since you would not need rebuild-test-release your application when only your config changes.
Theoretically, If an application running in user mode can -anyhow- access the plain sensitive data, so can the user(de-obfuscation, memory dump etc). Since all information needed to generate or decipher the sensitive data is present offline (code, disk, memory), one -with enough skills- can determine the decryption scheme by examining the code (even the machine code)
Think of an application as a user with rapid calculation and massive memory skills so it can de-obfuscate your code on the fly and do the needed calculations to decrypt the "safe" data
It's impossible that the config file/data is only readable for the program but not for the user, because you can decompile the program and search for the conection String, but you can make it to the user as hard as possible.
You can also write a php script or something else that checks the request and can block requests from specific ips if the script notice that the user spam requests or send rubbish data.
Perhaps it is enough to you also, that you create a new database user which limited write and read permissions has, so that the user didn't have the opportunity to do bad things with the Connection String.

Seeking Advice on Design for Multiple Users working in the same file

I am at the earliest stage of writing a desktop application for use by multiple users. I am looking for advice on what is the best way to approach this.
The Spec
I will persist my Model in a file which would often be used on a mapped network drive. (It is for the design of roadways and other linear features like railways and streams.)
The various end users need to be able to connect to and edit the file simultaneously. For example, Billy Bob is working on the road named US321 while Rupert is working on I40. The models for each road live in the same file. End users can "claim" any road name, in which only the claimant can edit the given road. Rupert can't edit US321 while Billy Bob has it claimed, but Rupert can read US321 for reference. Once a user is finished editing the road data, he can release the claim and someone else could edit it.
Limitations on Serialization?
My understanding of Serialization is quite limited (see my profile). But it looks to me like there is a one-to-one correlation between objects and serialization files. So if I use serialization to implement this, it would not be possible to claim just a part of it nor would it be possible to update only a part of it. (Is this correct? If not, then I can use Serialization, right?)
The Solution I am Considering
I am considering using SQL Server Express, and I am interested in the community's warnings, corrections, or affirmations on this.
The end users would not have to know that I am using SQL Server Express in the background. (I would even change the file extension to something suitable to my app.) I would load roads into a list, and each road would be "claimable". Claiming a road would mark it in the database for the other instances of the app to react to accordingly, kind of like it is a shared MS Excel file that multiple people can edit simultaneously, but (in the analogy to Excel) being able to lock individual worksheets.
[Edit] See Micah Armantrout's very informative response, below. So now I am wondering about using Microsoft Access as the intermediating db app.
[Edit]
Conclusion
Thanks to everyone for their helpful answers and comments. Micah's answer was very helpful since I did not realize I would be limited to the file being controled by only one server. Although it makes perfect sense now, I had not anticipated it, and if I had gone that route, I would have run aground on it after many hours of working in that direction.
When I first read urbadave's idea, I dismissed it as something I had already considered and not liked. But after thinking it over, it is clearly the simplest approach. I just use a directory like it is a file, but with user-transparency to my my top level sub-objects. But there clearly is an appeal to having my whole model be encapsualted into a single file.
So this is what I have decided to do: Start with just writing to a directory, just as urbadave suggests. Then later test out putting it in a zip directory and using the ZipPackage class to pluck out and insert the individual serialized files (or XML files -- another decision I have to make some day).
Paul
SQL server will work for what you are looking for but if your going to have multiple users you need to have a machine setup to be a server. It will not do you any good to have sql server express installed on each machine It might be one of the users machines or an actual server with SQL server express you are going to need to set it up to be accessible outside of a current machine to do this follow this tutorial.
If you are using anything past windows XP SP2 you will need to open up the ports of the firewall follow these instructions this is also talked about in the link below.
http://blogs.msdn.com/b/sqlexpress/archive/2005/05/05/415084.aspx
As far as sharing data I mean seeing other peoples work. If you are not wanting to install sql server on a server you can use MS Access I would refer you to a article on which one to use when
http://www.techrepublic.com/article/should-you-use-sql-server-express-edition-or-microsoft-access-for-your-small-business-applications/6140859
While I have access to a nice database at work, most of my personal programming does not use a database. One of the tricks I've used in the past is that file extensions are meant to carry meaning. In your case, you can exploit file extensions to indicate claims and control writing to the master file.
You're right, you would want to serialize each road object to its own file. The Master File would be the serialization of a collection object that holds all of these individual road objects.
The users select and open these road files. Before opening the file, the user's app re-names the file, adding an extension (perhaps the user's id). This way, you can use directory scans to find claimed and unclaimed files.
The master file is only written to when the user releases their claim on the road they are working on. The user's app opens all the road files, assembles a master object using the road objects and then serializes this object into the master file. When finished, the users app releases the user's claim on the road file by renaming it.
Before writing to the master file, the user's app renames the file, indicating it is about to be written to. If an users app needs to write, it can check to see if the file is renamed, and wait for the file name to be restored to a writable name.
This is a sketch of how I would attack this spec. Good luck.

Where to store application settings

I am creating an app that reads some info from a scale via RS232 serial port connection. There are a couple of types of scales that are in use, so I would like to store specific settings for the scale in my program. What is the best way to do this? Via app.config? Or should I put the values in a database?
It really depends on where will these configurations be used?
If you are working on a distributed huge system, which means these configurations are probably shared/used by other systems. You'd better store it in the database, with a common protocol which other related systems agree with.
On the other hand, if these configurations are used for a small application, storing them in a config file(or an xml file whatever you like) is suggested because, you don't need a gun in order to kill a mosquito.
app.config would be the easiest option for you. I think a database might be a bit overdoing it for just some settings, but if you wish to use something outside of what is offered by VS (namely app.config) then you could always whip up a quick custom XML settings file. All depends on what you wanna do with it and how comfortable you are with the other technology.
Is the information chaging ? that means when you ran ur app , would it be the case that information is updated ?
if the information is static and do not change frequetly , you can store in the app.config.
or in a xml file and you can read that information lately.
but if the information is dynamic then you need to create a model and expose scale information through model's peroperty.
Do not forget the registry.
Use the registry when:
You need your settings to be accessible for a domain admin
you need to secure some settings (using Windows security)
(You can make some settings read-only)
There are a lot of small settings that change very often
If it's simple and straightforward than app.config is the way to go - you don't need to set up a database and you get to use simple built-in interfaces.
If you choose to go with a database check out mysql for a simple file based database that has a simple deployment scheme.

Understanding .Net Configuration Options

I'm really confused by the various configuration options for .Net configuration of dll's, ASP.net websites etc in .Net v2 - especially when considering the impact of a config file at the UI / end-user end of the chain.
So, for example, some of the applications I work with use settings which we access with:
string blah = AppLib.Properties.Settings.Default.TemplatePath;
Now, this option seems cool because the members are stongly typed, and I won't be able to type in a property name that doesn't exist in the Visual Studio 2005 IDE. We end up with lines like this in the App.Config of a command-line executable project:
<connectionStrings>
<add name="AppConnectionString" connectionString="XXXX" />
<add name="AppLib.Properties.Settings.AppConnectionString" connectionString="XXXX" />
</connectionStrings>
(If we don't have the second setting, someone releasing a debug dll to the live box could have built with the debug connection string embedded in it - eek)
We also have settings accessed like this:
string blah = System.Configuration.ConfigurationManager.AppSettings["TemplatePath_PDF"];
Now, these seem cool because we can access the setting from the dll code, or the exe / aspx code, and all we need in the Web or App.config is:
<appSettings>
<add key="TemplatePath_PDF" value="xxx"/>
</appSettings>
However, the value of course may not be set in the config files, or the string name may be mistyped, and so we have a different set of problems.
So... if my understanding is correct, the former methods give strong typing but bad sharing of values between the dll and other projects. The latter provides better sharing, but weaker typing.
I feel like I must be missing something. For the moment, I'm not even concerned with the application being able to write-back values to the configuration files, encryption or anything like that. Also, I had decided that the best way to store any non-connection strings was in the DB... and then the very next thing that I have to do is store phone numbers to text people in case of DB connection issues, so they must be stored outside the DB!
If you use the settings tab in VS 2005+, you can add strongly typed settings and get intellisense, such as in your first example.
string phoneNum = Properties.Settings.Default.EmergencyPhoneNumber;
This is physically stored in App.Config.
You could still use the config file's appSettings element, or even roll your own ConfigurationElementCollection, ConfigurationElement, and ConfigurationSection subclasses.
As to where to store your settings, database or config file, in the case of non-connection strings: It depends on your application architecture. If you've got an application server that is shared by all the clients, use the aforementioned method, in App.Config on the app server. Otherwise, you may have to use a database. Placing it in the App.Config on each client will cause versioning/deployment headaches.
Nij, our difference in thinking comes from our different perspectives. I'm thinking about developing enterprise apps that predominantly use WinForms clients. In this instance the business logic is contained on an application server. Each client would need to know the phone number to dial, but placing it in the App.config of each client poses a problem if that phone number changes. In that case it seems obvious to store application configuration information (or application wide settings) in a database and have each client read the settings from there.
The other, .NET way, (I make the distinction because we have, in the pre .NET days, stored application settings in DB tables) is to store application settings in the app.config file and access via way of the generated Settings class.
I digress. Your situation sounds different. If all different apps are on the same server, you could place the settings in a web.config at a higher level. However if they are not, you could also have a seperate "configuration service" that all three applications talk to get their shared settings. At least in this solution you're not replicating the code in three places, raising the potential of maintenance problems when adding settings. Sounds a bit over engineered though.
My personal preference is to use strong typed settings. I actually generate my own strongly typed settings class based on what it's my settings table in the database. That way I can have the best of both worlds. Intellisense to my settings and settings stored in the db (note: that's in the case where there's no app server).
I'm interested in learning other peoples strategies for this too :)
I think your confusion comes from the fact that it looks like your first example is a home-brewed library, not part of .NET.
The configurationmanager example is an example of built-in functionality.
I support Rob Grays answer, but wanted to add to it slightly. This may be overly obvious, but if you are using multiple clients, the app.config should store all settings that are installation specific and the database should store pretty much everything else.
Single client (or server) apps are somewhat different. Here it is more personal choice really. A noticable exception would be if the setting is the ID of a record in the database, in which case I would always store the setting in the database with a foreign key to ensure the reference doesn't get deleted.
Yes - I think I / we are in the headache situation Rob descibes - we have something like 5 or 6 different web-sites and applications across three independent servers that need to access the same DB. As things stand, each one has its own Web or App.config with the settings described setting and / or overriding settings in our main DB-access dll library.
Rob - when you say application server, I'm not sure what you mean? The nearest thing I can think is that we could at least share some settings between sites on the same machine by putting them in a web.config higher in the directory hierarchy... but this too is not something I've been able to investigate... having thought it more important to understand which of the strong or weak-typed routes is 'better'.

Categories

Resources