Where are my application settings stored exactly? - c#

With a Windows Forms (or WPF) application, if I create an installer through Publish command (ClickOnce that is), the installer creates application folder with executable and config file in C:\Users\[UserName]\AppData\. On the other hand, if the installer is created through Setup project (MSI), the installed app would be in C:\Program Files\My Company\My App with both the executable and the config file. Out of the two, I chose MSI path.
My expectation was that the application settings (as in Project properties > Settings tab) are read from/written to the config file that is in Program Files, which remains there even if I uninstall the program or upgrade it with a newer version, so that user's settings don't get lost. But it doesn't appear to be the case. Even that the Program Files version of the config file is there, the installed application appears to be reading from/writing to C:\Users\[UserName]\AppData\ as if it were a ClickOnce app. What am I missing?
(This is VS2010 + Win7 + C# + .NET 4.0 Client Profile, though I don't think those things have anything to do).

I hope I understand your question in the right way.
If you want to know, why settings are read from/written to the AppData folder, then it's because of security/permission reasons.
When first starting your application, your initially application settings from app.config file were copied to that folder. Your application will automatically work on that newly created file.
This is done, because it's a risk letting the user work on the "global" settings in your Program Files folder, with which all your users will work. Think about what would happen, if a user only has permissions to read, but not to write to this file.

Related

How to allow for editable .Net generated config files with MSIX?

I am trying to help port a .Net service to a more modern .Net version (possibly Core) and use the MSIX installer. The application has several configuration files generated by the compiler (in source they are app.config but compiled they become *.exe.xml), they are installed into Program File right next to the binaries and a GUI helper app as well and the application itself can modify them to change service behavior (port, ip, tls cert, etc).
Writes under C:\Program Files\WindowsApps\package_name are not allowed.Writes under C:\Program Files\WindowsApps\package_name are not allowed.
The problem I am facing is that the MSIX installer makes it so that files in it's sandboxed version of Program Files cannot be written to (see above). That means that this application cannot be configured, so I am trying to figure out not only how to make the app configurable again, but also how windows wants to handle app configuration.
Right now it seems like there is two general approaches to do this:
write the configuration data to the service account's AppData/local folder
try to mimic a /etc/Myservice behavior in another folder. (meaning a local system-wide directory that houses configuration data for the service)
If you suggest #1 please answer the following additional questions:
How would I move Application configuration files to a user configuration file directory
how can an admin with a normal account modify the config file in the Service Account's AppData folder with the mentioned GUI helper application? (do they need to enable desktop access to the service account, login and run the GUI)?
If you suggest #2:
Where would you suggest this directory exist (specifically where will MSIX allow it)?
How do I tell the .Net application that the files are not right next to it? Can I just use AppData.CurrentDomain.SetData?
Well, a service running on the system account is the same for all users, so I would say that CommonApplicationData is a better folder for storing its settings, instead of appdata. This folder is easily accessible to both your service and to any admin that needs to deploy a custom config file.
In AppData you should store only actual user files (like files or settings generated by the actions taken inside your app by a specific user - thus different files for different users).
Now, the second part is where you need to configure you code to load the config file from a custom path instead of looking for it next to the EXE. I am no .NET expert but after a quick search I found this:
Relocating app.config file to a custom path
The modern approach to deploying app customizations
What is not clear to me is how your customers use the GUI helper tool to customize the config file. Is this just a tool that is used by someone from the IT department to generate the config file, and then they would copy that file and deploy it to the end-user machines using an MSI/MST file (or through some other custom deployment method)?
If your application is only deployed by IT folks, then you can try another simpler (and much elegant) solution for providing it with a custom config file, which actually doesn't require any code changes.
You can still leave the config file next to the EXE, in ProgramFiles and instruct the IT teams that deploy the app to use an MSIX Modification Package to deploy the custom config file generated by your GUI helper. (check the link included above for an example - with a video version at the end of the article).
Note: IT teams can use multiple free or paid tools to generate MSIX Modifications Packages.
Of course, your GUI helper tool still needs to generate that customized config file in a folder where it is allowed, as it can no longer write under ProgramFiles. So actually, you do need to modify a little bit your code in this scenario too.

Deploying Windows forms application with Config

I am trying to deploy a windows forms application which uses the properties/settings of the project to store config information.
In a form it is retrieved and sometimes changed by saving as below
Properties.Settings.Default["name"] = textBox1.Text;
Properties.Settings.Default.Save();
I only need to deploy to 3 PCS. Is it enough to deploy the .exe file alone?
Or do I also need the exe.config file ?
Thanks
If your App.config1 file contains default configuration information not embedded in your program, such as a connection string, then yes, you will need to bundle it with your executable.
However the code you've posted shows you're using the "Settings" feature, which is a feature of .NET that runs on-top of App.config. If you use the Settings feature, then your app.config file is (usually) actually stored under your current user's AppData directory and not the same directory as the executable, these files are also created as-required, in which case you won't need to ship the app.config file... assuming you have nothing else in the file.

What is the right way to create a config file that can be modified by a user with no admin rights?

My C# program has an app.exe.config file. User can install the program anywhere. If the user chooses to install the program in the "Program Files" folder, the program will have privilege problems modifying files in Windows 7, so I've externalized the files that can be modified to the AppData folder. Except app.exe.config file, that should also be modifiable by the program when user changes its settings. Apparently it should be in the same folder as where app.exe.
I think this is a quite trivial problem, however I cannot find the right solution.
Copying the config file elsewhere, modifying it and copying back to Program Files;
Creating a second config file elsewhere;
Not giving the user the choice of installation folder;
Forcing the program to be run as admin.
All of these solutions would lead to a bad design. What solution wouldn't?
EDIT: Maybe some of my premises are wrong and it is possible to have the config file installed to AppData or anywhere else without changing the executable's location. I haven't yet found for sure if this is possible, however.
The Application Settings Architecture should help you - you can define user settings as well as application settings that are stored in a user.config file.
Reference to MSDN: http://msdn.microsoft.com/en-us/library/0zszyc6e(v=vs.110).aspx
"Non-default user-scoped settings are stored in a new file, user.config, where user is the user name of the person currently executing the application. You can specify a default for a user-scoped setting with DefaultSettingValueAttribute. Because user-scoped settings often change during application execution, user.config is always read/write."
Change app.config file permissions upon installation. If you are using WIX (I'm just assuming since it's the most popular solution nowadays) have a look at http://wixtoolset.org/documentation/manual/v3/xsd/util/permissionex.html

Updates made to application config are only being read correctly in Windows 7 when the application runs as Administrator

We have an application that was built for the Windows Mobile and Windows platforms, using Visual Studio 2005. We have both versions of this application developed using a single code base to try and reduce code duplication. One of the issues that we encountered with this was that the ConfigurationManager was not available for the Windows Mobile platform. We worked around this by building our own ConfigurationManager that reads and writes settings to the "Application.exe.config" file in the Program Files folder. So both our Windows version and our Windows Mobile version use this same custom ConfigurationManager.
This worked fine on Windows XP and Windows Server 2003, but on Windows 7 we have encountered a problem and I don't know how to work around it. When we make a change to the config file (which we can only do by copying it to another folder, changing it and then copying it back... otherwise we get an "access denied" message when we try to save our changes directly in the Program Files folder), the change that we make is only reflected if we run the application as Administrator. If we run the application as a normal user, the default setting from the install are always shown. We suspect that this is a Windows 7 security-related issue, but can someone explain why this is happening? How can we change the settings so that they are also applied when the application is run as an ordinary user?
Windows 7 requires elevated privileges for several folders, including program files. It's not good practice to try to work around this.
Since you are using a custom solution, one option is placing your configuration file under %APPDATA%\yourproduct, which can be reached with
var appDataFolder = Path.Combine(Environment.SpecialFolder.ApplicationData, product);
A better solution is probably to use different configuration managers for different platforms, though. Couldn't some kind of abstract factory be applied?
I suspect your app tried to write to the config file at least once running non elevated and without a manifest. This made a "compatibility files" folder for your config file. When you run non elevated it looks there now. (See http://www.gregcons.com/KateBlog/FindingFilesYoureSureYouWrote.aspx for screenshots of how you can confirm this.)
If all you want is for a human, or some utility program you wrote that can run elevated, to be able to edit the config file, you can leave it where it is and put a manifest on your app to prevent virtualization. See http://www.gregcons.com/KateBlog/AddingAManifestToAVistaApplication.aspx for a sample manifest. That blog post goes on to tell you how to embed the manifest, but you don't need to, an external manifest will work. If your app is foo.exe, name the manifest foo.exe.manifest and put it in the same folder. This will prevent virtualization and cause the app to read the "real" config file.
If changing the config file will be a normal everyday occurrence, don't write the file under Program Files. AppData is a good choice.

C# console app deployment

I have a simple C# console application developed on my local machine using VS2008 Pro. I want to know how to deploy this solution onto a network share folder?
A similar Java console program is already placed (as a JAR file) in the same network share folder. Users simply open command prompt, navigate to shared folder and type "java -jar programName.jar inputParameter1 inputParameter2"
How can I achieve the same with .NET?
You can copy the exe over yourself, go to the bin folder in the directory your source code is in and copy it there.
or you can click the BUILD menu and use the PUBLISH menu item. This will allow you to enter the path to your network share and visual studio will copy the built app to the folder for you.
If your application is really "simple", you should be able to just copy the files to a shared folder and run it from there. However, if your "simple" application tries to do things that are restricted by the permissions you might have to configure them with caspol. Assemblies loaded from a shared drive have much fewer permissions than the ones loaded from a local drive.
It would be mostly the same process as the Java program. To deploy, compile the program and copy the exe from the bin folder (along with any dependencies) to the network share.
To run the program users would open the command prompt, navigate to shared folder, and type "programName.exe inputParameter1 inputParameter2"
You can use Publish feature of VS. Note that you can change settings in the Publish section of the console application project to remove some features that you don't need. For instance the renaming of .dll and .exe files by appending the '.deploy' extension to the name of the files or publishing in a new 'version' folder each time. Go to "Project Properties"->"Publish" and remove "Automatically increment revision" checkbox at "Publish Version", click "Options..." button and clear all checkboxes there too.
Right click your project, select publish which will make an executable, you can put that in your shared drive, similarly users can go into the command prompt and run it and give some args.
In the exact same way assuming they have the proper dependencies installed (.net, 3rd party assemblies, etc). copy the bin folder then have them execute the exe file.
Take a look at ClickOnce deployment:
ClickOnce is a Microsoft technology
for deploying Windows Forms or Windows
Presentation Foundation-based
software, also called Smart clients.
It is similar to Java Web Start for
the Java Platform.
MSDN
Wikipedia

Categories