Change settings of local system account - c#

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

Related

LocalApplicationData is different in service programs than in console apps

I am creating a service that access a folder path:
string localAppDataFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
Unfortunately, the folder returned is not:
C:\Users\mainuser\AppData\Local
... but:
C:\Windows\system32\config\systemprofile\AppData\Local
...instead.
mainuser is the user that is currently logged in. Is it possible for service to launch a program that is placed in current users AppData\Local? I am aware that you can go to Services-> Right click Properties-> Log on and type in password and account name, but I am looking for a programmatic solution, ideally using sc create command.
Alternatively, I can move all folders in interest to C:\ProgramData and completely avoid current user. Is there a way to keep the files in users AppData\Local and use programmatic solution without password?
In short, Services don't (and shouldn't) launch programs for users or access user information in general (unless they run as the specified user). They are agnostic of users and their profiles, their use-case is to run as part of the system
If you want to run an application when a user logs on, either use a group policy, or add it to the user settings to run on startup. If need be, set this up in the installer
This is the way every service works, and the norm for windows for a long time (with the exception of drivers)

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.

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.

Applications that remember preferences during the next logon

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)

Configuration GUI Deployment, Place in the same directory? C#

I am writing a GUI to configure my service written in C#.NET 3.5, it edits an embedded SQLite database from which the service pulls its settings. The GUI is being developed in a seperate project and I am at the point where I would like to integrate them. It is my first time implementing someting like this and I am unsure how I go about it.
Do I simply place the GUI .exe file in the same directory (bin?) as the service and give it the location of the database?
Yes, usually. You will however have to ask for elevation or you won't be able to write to the dbase. UAC prevents write access to the directories in c:\program files. Which is okayish, the user is after all tinkering with the configuration of a privileged service. And you probably need to stop and start the service to make the configuration change effective, something you can only do from a privileged program. Embed a manifest in gui.exe as explained in this post.
Pre-empting the next question: there is no standard Windows way to have to dbase in a location that's accessible to both the service and your gui without elevation. You'd have to write an installer that creates a directory that gives the gui app sufficient rights and allows the service to find the directory without relying on the user name.

Categories

Resources