Maintaining a program folder in program files out of date? - c#

For the program I'm writing in vs C# wpf I need to store some user related information on the user's computer. As far as I knew this has almost always been done by creating a folder in C:\Program Files and adding whatever program related info to that folder in subfolders or whatever. After doing some browsing I came across a lot of people saying that this method is out of date because sometimes access may be denied to create a folder there, it only works for administrative accounts, etc.. One site suggested saving to c:\users\username\appdata\roaming or c:\users\username\appdata\local. So my question is what is the best and most up to date method for saving program data to users computer?

Also take a look at this MSDN article.
It is mainly for UWP apps but you will have a general idea what to put where even if you are developing a WPF app.
You may need these folders:
Environment.SpecialFolder.ApplicationData
Environment.SpecialFolder.LocalApplicationData
Environment.SpecialFolder.CommonApplicationData

Take a look at this microsoft developer blog Where Should I Store my Data and Configuration Files if I Target Multiple OS Versions:
Here is an example where you can store your Local per user configuration files
Configuration data files that the application uses and is unique per user. It stays local to the individual machine and is not synchronized via Active Directory.
Example: MyMachineSpecificData.xml
Windows 7: %USERPROFILE%\AppData\Local\<MyCompany>\<MyApp>
Vista: %USERPROFILE%\AppData\Local\<MyCompany>\<MyApp>
XP: %USERPROFILE%\Local Settings\Application Data\<MyCompany>\<MyApp>
So basically per user config files should go to:
%USERPROFILE%\AppData\[Roaming,Local]
If those configs should be available to all users then:
%SystemDrive%\ProgramData
For per user data you can use Libraries. For user independent access C:\Users\Public.
Additionally you can also use windows registry to store your configurations.

Related

C# WPF - Deployment of application with local database sqlite for every user on computer with VS2019 Setup Wizard

I developed an application in WPF for local usage on a computer. This application contains a database file (SQLite) where the user can store and read data in it. This means the database file needs read and write permissions. I deploy the application with the Setup Wizard of Visual Studio 2019.
I can install the application on different computers and the application works. After the installation of the application the database file will be stored in the User's local app data folder like ...Users/Username/AppData/Roaming/...
The problem is, this database can only be accessed by the user who installed the application. But I want that all users on the local system have access on this database file, so that the application will work on every user account on this computer.
So I need a folder location where every user and new users in future have access to store my database file. Additionally I've tried to store the database in the application folder (it's like C:\programms..., the standard thing), commonAppFolder (which is like C:\ProgramData) but nothing works because of the missing permissions in this folders. Is there any folder what I can configure my Setup wizard with? What is with the public folder in c:\users\? I have no options to choose that path in the setup wizard (no special folder or something)? Is there any recommended method of solving my problem with a database file that must have read/write permissions for every user, so that the application works for every user on the computer?
Hope you understand it, English is not my natural language.

Does WinRT have a storage option that persists even after uninstalling the application?

I am trying to put some files and folders in a place that my WinRT application could access and read files from. These files and folders must be locked and permanent even when I uninstall the application.
There are 4 main categories of folders that you have access to from a Windows Store Application:
/AppData/Local/<yourpackage>
Standard available libraries (Music, Pictures, Videos)
Libraries that require elevated permissions (Documents)
User-defined folders (through a FilePicker)
Typically you will store data specific to your application in the first kind and data for the user in a library or a user-defined folder.
When your application is uninstalled, its package folder under /AppData/Local is removed so there is nothing left there (note that this contains the directories which you get using ApplicationData.Current.Local and ApplicationData.Current.Roaming).
Therefore in order to save data persistent through installations you will have to save them in a different directory. Note however that in the case of option 4, the user might not decide to give you access to the folder he picked out the previous time or that he doesn't want to give the application access to the Documents library.
I think a more solid solution would be to save the data on a remote location so that the user can download it when he installs the application again, rather than relying on everything being saved at the user's device.
With regards to the locking: you could look into the DataProtectionProvider and see if that suits your needs.
To reiterate Jeroen's response:
To save data locally in a place that won't be deleted when the app is uninstalled, you must use the file picker to have the user choose a location.
Saving the data remotely is the only option that doesn't require user interaction.
It's possible to save data in the app's roaming settings, as those are retained for some period of time after the app is uninstalled. If the user has the app installed elsewhere, that data will be retained continuously. If there are no other installations, it will be retained for around a month.
I recently wrote a blog post addressing this exact scenario in more detail, including how to get a persistent user identity for any data your store remotely: http://www.kraigbrockschmidt.com/2014/07/31/persisting-data-after-uninstall/.

C# Application deployment: Failed to update database because the database is read only

I have actually gone through stackoverflow answers for the same question asked before. I understood that this problem is being caused because of restricted permission in Program Files folder.
I have gone through this answer at https://stackoverflow.com/a/5714111/1182021, and the same solution is being all over the web
If the MDB file is in your application path, then the default permissions would require elevation of rights to be able to write to the files -- I'd recommend moving the data to the ApplicationData shared folder, where end users will have write permissions by default
My query is in continuation to the above solution only:
I have globally changed my database path to Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) and from there I wish to access my database as it will be a public access folder (I surfed and came to this conclusion)
How to define this while deploying the application? Means when I am deploying my Setup and Deployment project it automatically puts my database files in my C:\Program Files\MyApplication\ and so my application is not able to access the database at the ApplicationData folder.
Secondly, is this the only way? Can't I get my database into my installed directory and give full permission to my application to access my DB?
I have definitely read TomTom answer at https://stackoverflow.com/a/14611895/1182021 but still if any trick that can do and which is feasible and advisable.
Okay I dont know why I didn't got any answers yet. Was really trying to fix this issue and finally found the solution.
On your Database global configuration file that you have created within your project to manage all your database related work like add, delete, update and connection. For a local database define a LocalDbPath like this:
public string LocalDBPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
Then use the same LocalDBPath everywhere in your database connection.
While deploying the project via Setup and Deployment go to:
File System Editor
Right Click on File System on Target Machine
Select Add Special Folder
Select User's Application Data Folder
And Add your Database file by going into User's Application Data Folder -> Right Click Add -> File and choose the file.
Build your solution and you are good to go. Cheers!

Consistent ApplicationData path between WinForms Apps and Windows Service contexts in C#

I use the following code to build a desired path for an XML file:
System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData);
When executed from a Windows Forms application, it returns:
C:\Users\MyUsername\AppData\Roaming\...\Database.xml
When executed from within a Windows Service, it returns:
C:\Windows\system32\config\systemprofile\AppData\Roaming\...\Database.xml
I am now resorting to having a custom installer action persist the path in a registry key since the custom action will have a desktop context. If there is a better approach, please let me know.
What I am really interested in finding out is why the behavior is different in the first place. The Windows Service in question is set up to use the LocalSystem account in case that matters.
Only you know what the specific requirements are for this folder, but if it's to share data between multiple users, ApplicationData is the wrong choice:
The directory that serves as a common repository for application-specific data for the current roaming user.
A roaming user works on more than one computer on a network. A roaming user's profile is kept on a server on the network and is loaded onto a system when the user logs on
See the SpecialFolder enumeration and pick an appropriate value that fits your requirements - one that doesn't depend on a specific user. Most of these start with Common.
I suggest that you should check and make sure that two apps are running by the same user.
I tested your code in both winform app and webservice app, but their values are the same, so I can't find your real problem.
good luck!

Where to store data securely from a Windows service?

I'm writing a service using C# that is supposed to run on a Windows platform as the "local system". I can store small amounts of data in the registry, but if I want to store more data in a file, where do I place such file in? And also how to protect that data from a modification by users with lower access rights?
General approach is to use ProtectedData class to encrypt the data, then store them anywhere on the disk where the application can (eg in a subfolder of LocalApplicationData special folder, whose location you can obtain using Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData call).
Update to previous answer that may save some troubleshooting time to people using this solution (as I don't have enough reputation to comment):
For Local System Windows service account, Environment.SpecialFolder.LocalApplicationData
may also be resolved to
C:\Windows\SysWOW64\config\systemprofile\AppData\Local instead of C:\Windows\System32\Config\SystemProfile\AppData\Local.
Using the already mentioned CommonApplicationData instead of LocalApplicationData does not bring this issue.
Information source: https://www.jamescrowley.net/2014/02/24/appdata-location-when-running-under-system-user-account/

Categories