Applications that remember preferences during the next logon - c#

My Simple C# application contains a settings window. It actually prompts to set or reset password. Currently, I'm saving these preferences using database and displaying it accordingly during next logon.
I wonder if there could be an easy way to make the application remember those preferences when we open it for the next time.
Possible?

There are several ways to save preferences. You can use the built-in settings system through Properties.Settings.Default.yoursetting, you can use IsolatedStorage System.IO.IsolatedStorage, you could simply write a file to the application directory, you could save it in the registry by creating your own registry key. If you want something easy and simple, use the built-in settings by going to the solution explorer, open up the Properties folder and double-click on Settings.settings. Add the settings fields you want and you can access them through Properties.Settings.Default.yoursetting

if it is a normal preference or if you don't really care if someone can just read the user's credentials and use it then it's fine to store it in a config file somewhere. You can also choose to encrypt the credentials and store it some where. However, I would rather use the windows' build in credential manager to store log on information the same way TFS does for example.
"Control Panel\All Control Panel Items\Credential Manager"
storing-credentials-in-credential-manager-service

First thing to do is to have a clear understanding of your settings:
I will summarize how I usually categorize the options of an application.
I call them "DomainOptions", "MachineOptions" and "UserOptions"
DomainOptions are settings that define the behaviour of your application for every user and from whichever machine they run the app. These setting should obviously stored in the shared database and just a restrict number of users should be able to modify them (I.E. the uri of a web service, the shared folder for application data, the fixed tax value required by your local regulations and so on)
ApplicationOptions are settings that define the behaviour of your application when it is started by a specific machine. Think, for example to a machine that has VPN connection and need to authenticate before running the app. These settings could be stored in the app.config or other local storage (avoid at all cost the REGISTRY), but keep in mind that if you need to change these values at runtime you can't write them in the configuration files for the Application section because it is read only at runtime. In this case I suggest to write your own class to store some sort of XML files in your common application data directory (Environment.SpecialFolder.CommonApplicationData + yourappfolder)
UserOptions are settings that every user could personalize like colors, window positions, accessibility parameters and so on. These could easily stored through the configuration files (User section) because they are modifiable by every user. However, if you have also a class to store the ApplicationOptions it is trivial to implement a variation to store these settings in the Local application data. (Environment.SpecialFolder.ApplicationData + yourappfolder)

Related

Application permanently store variable value

I am using Properties.setting.default.var to permanently store a value in a C# application on the same PC.
Now I am facing a problem that when I save the value but copy the application to another PC, the permanent value does not remain. Does the properties.setting trick not work in this scenario? If yes? Please advise the solution.
You need to get the settings stored in location that is accessible by all devices you plan to run your program on.
You can either
make sure current location of the settings file is synchronized between all devices - this way you can keep your existing code. You can sync files via roaming profiles in Windows Domain, by letting some file share synchronization tool to sync that file - i.e. OneDrive, by just manually copy file or any other way you can find.
write settings file yourself to shared location which can be accessed by all devices - pretty much any service that allow to upload data would do. Some will allow authenticated access so you can limit settings to particular user (OneDrive, GoogleDrive,...), some some form of anonymous/semi-authenticated uploads (which make personalized settings a bit harder and make them public for all to see). You may still be able to use some of the existing code but likely getting your settings in JSON format and uploading would be easier.

Change settings of local system account

I am adapting a program I wrote to run at user login in the system tray to do it's work as a service while another instance may run in the tray for configuration access. The plan being to save any changes when made and restart the service with the new configuration.
In my original program I used project settings to store my configuration ([MyProjectName].Properties.Settings.Default). When it is run as a service it uses the local system user account which means it has different settings than when run with access to the tray.
Before I move to a different configuration strategy, is it possible to change the settings for the local system account from my instance run as a normal user?
It is possible to modify the settings file of another application by parsing its configuration file. You will need write permissions for wherever that file is stored. You could grant these to your normal user account on runtime.
However, I think that directly modifying another applications settings file is a pretty hacky way to do it. It would be wiser (and probably easier) to store the configurations in a more standardized location that can be easily accessed by both applications, like ProgramData or Program Files

Make a file read/write accessible only from within my application

I'm creating a new database application using C# and MS-Access, I want to make the database file ONLY accessible for (read/write) operations from within my application so that the user haven't the ability to open the file from outside the application but the application has the full access to the database file, Or may be a better way is to make this permission for the root folder of the database.
Someone may ask "Why don't you just set a password for the database?"
My reply is that I want the root folder completely inaccessible and therefore the user won't know the database type I'm using because I will change the file extension for it.
As far as I know that the Windows OS uses the NTFS permissions -Groups- to make a folder accessible only for a set of groups like (Trusted Installer, System, Users,...)
Can I Achieve my goal using NTFS Permissions, or may be there is a better way to handle this?
I added fixed length encrypted bytes to the start of file using low level file read write operations and my app upon execution removed the bytes and had given me the actual file and I blocked the starup menu and short cuts keys and context menus using windows api so only my app had access to it plus I enabled windows stuff upon app termination and encrypted database again so it was unreadable for another access enabled app.

Synchronization xml file across multiple servers(machine)

In our application there are multiple client applications.
One client application is setup on a separate server(machine).
There is a module named as reconciliation, preferences(setting) of this module are saved in xml file on hard disk of each serer.
My requirement is that i want to share preferences of one server to another server for view purpose only.
i.e. user u1 on server A can view preferences of server B but can't edit these preferences.
The main thing is that preferences should be real time synchronized with the server.
i.e. user u1 on server A is viewing the preferences and at that time a user on server B changes the preferences then preferences should be updated on server A for all users.
You could use some sort of pub/sub system that each application is listening to. When a preference is saved it will publish a message with information about whose preferences have changed. Each application is also subscribed to the system and will receive the message saying something has changed. You can either publish the preferences with the message of store them somewhere centrally and have each application go and retrieve them
Another option is to store the preferences in a shared folder (maybe one file user preference) and have your applicaton watch that folder for changes. When the user file changes you can reload the file.
If you choose to save the preferences in the database then you'll need to poll the database from time to time in order to see if anything has changed. You can avoid the polling if you go with a pub/sub system, but if you don't you'll need to think about how often you poll the database and how it will scale when you take into account the number of instances of your application are running and how often you check the database.

Deploying default settings for different customers

My question is sort of linked to this existing question
How to deploy a desktop .Net application with custom settings per user
However, I understand the idea of using Application Settings what I can't find information on is, how should I deploy the application settings for different customers?
We have a custom settings system that works just fine, however when the app is first run it needs to know a couple of things, such as Company Name and Application Server. These will obviously differ on a customer basis.
I don't want the user to have to input these settings at first run as in most cases the app will be deployed by Group Policy.
Currently my thinking is to have some sort of setting file in a separate build per customer. Is this the way to go, or have I missed some kind of native support for this idea of "customer profiles"?
EDIT:
More info that might help people grok my question.
This is an enterprise application that consists of a central database and application server, plus 100 installations of a client application. I need to be able to give the client application some application settings that will obviously be different for different customers.
A lot of applications ask you some initial settings at the first start (Microsoft Office, Visual Studio, etc.). So this behaviour is commonly known by the user.
Maybe the problem is more, that these initial settings revive an update of your application. To accomplish this you could save your data in a version independent path within the registry or somewhere below %AppData%.
Also it would be helpful to prefill these dialogs at the first startup, by getting these informations somewhere out of the machine (e.g. Company Name can be get from registry [HKLM\Software\Microsoft\WindowsNT\CurrentVersion\RegisteredOrganization] or as Application Server take the Gateway address, AD Server, whatever most commonly matches).
So in a best case the user will be presented with a already correct filled out form and just has to press enter or he makes only the changes that are necessary, but doesn't to fill out the complete dialog by himself.
Update:
So if the user doesn't know the Application Server path. Who does it? Where resides this information? Maybe you can enforce your customers to provide this information all the same way. Maybe they set some environment variable within the logon script or they put a file with the needed informations on a global accessible place (e.g. where the logon script resides).
If I understand right you want to deploy a pre-customized software for each user.
You could use WIX to create a MSI-package for each customer. You can deliver several user-settings in your customer-oriented msi. You can dynamically generate a WIX-XML-Document based on a data-source where you store your customers.
Is a bit work, but later saves a lot of work. The MSI-creation through WIX can be easily integrated into the build-process.
Given that it's an enterprise environment, have you considered using ClickOnce? We've had success mainly with startup arguments, e.g. http://servername/OurApp.application?environment=uat
It doesn't always scale, but you can pass arguments using GET variables and parsing the resulting QueryString when delivering via HTTP - http://msdn.microsoft.com/en-us/library/ms172242.aspx
You might pass in the settings in the QueryString, or create them in the database, generate a (hashed?) key and build a QueryString unique to that reference (with the added benefit that an inquisitive user wouldn't be able to manipulate the URI and fake a different set of parameters).

Categories

Resources