How to access permission to files after installation? - c#

Today I finally ended creating my app.
To install app I used "setup project" from Visual Studio 2019 (image of project type). App is written in C# .NET 4.7.2 Framework.
So I added some folders and files (image of files and folders here). So I gave my friend *.msi file, he istalled that and something happened - path access denied.
I was surprised because when I installed, everything worked, but on my friend's PC when app is trying to write something in file, it gives result that it cannot open it (just doesn't have permission).
My friend went to properties of those files and he didn't have writing permissions (image here in polish language). In that picture in Polish, zapis
mean "writing", so here is my question: how to make setup project in Visual Studio which gives permission to folders/files to modify them?

In general apps don't have permission to write files to the program folders without elevated permissions. Most apps should write data to the users %appdata% folder you can access that path in c# using:
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)

Every work on files and folders must be in Users\user folders, in Documents\folder or in the registry. You shouldn't give permissions to the user to modify files on the system or Program Files.

Although windows installer is able to set file permissions, you should not write anything in Program Files. And you should not grant write permissions there due to security considerations and best practices. So, you need to inspect your code and change all places where you are trying to write in a Program Files (or in the folder where your application is placed) to write somewhere else. For example, in the %temp% folder, in the Program Data or in specific folder inside a user's Documents folder or even ask user to specify write location explicitly.

Related

After using InstallShield to install my app my sqlite .db file is being saved in the AppData directory. Why is that?

After using the free version of InstallShield and installing my app on my machine I noticed that my data file (a sqlite .db file) is being saved in a different location than when I run it under Visual Studio. Basically instead of being saved in the directory with the .exe file it is being saved here:
C:\Users\blaaah\AppData\Local\VirtualStore\Program Files (x86)\MyAppA\MyAppA
My .exe file with its .dll files is being saved here:
C:\Program Files (x86)\MyAppA\MyAppA
I am curious as to why that is happening?
I am also curious on how to get that directory that contains my data file with code.
The VirtualStore folder is caused by file system redirection done by UAC. By doing this, Microsoft was able to lock down the Program Files directory without sacrificing too much backward compatibility. Any time an application tries to write to the program files location, the write will be redirected to the Virtual Store.
A decent writeup on this on MSDN can be found in the User Account Control For Game Developers article.
To quote that article:
Virtualization affects the file system and registry by redirecting system-sensitive writes (and subsequent file or registry operations) to a per-user location within the current user's profile. For example, if an application attempts to write to the following file:
C:\Program Files\Company Name\Title\config.ini
the write is automatically redirected to:
C:\Users\user name\AppData\Local\VirtualStore\Program Files\Company Name\Title\config.ini
Likewise, if an application attempts to write a registry value like the following:
HKEY_LOCAL_MACHINE\Software\Company Name\Title
it will be redirected instead to:
HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\Software\Company Name\Title

Permissions on Application Folder

I have a default application setup created using Visual Studio 2005. When my application is installed, it's only work running as administrator, because some files are written in the Application Folder.
I have found that on Visual Studio 2010 there is a property for change this permission on some folders inside application folder.
How can I allow to my application create and edit specific files inside the application folder without run it as admin?
Here are your options, assuming that you cannot change where the application itself attempts to read/write files:
Change the default installation directory of the installer of the application, to not go inside C:\ProgramFiles, but instead to a folder just off the C:\ drive that has more lax access permissions. This was standard practice in Windows 3.1 and even Windows 95, but these days you can't get a program "certified" by Microsoft as compatible with any supported Windows version unless it installs into the proper Program Files directory. These modern OSes also have the root of the C:\ drive locked down pretty tight so you'd need administrative permissions to install the app (but not to run it).
Create a custom action for the installer which increases the access rights of the program subfolder during installation. Again, Microsoft is unlikely to certify the app if you do this, and this also requires admin permissions to install the app, meaning the average user on your network can't just pull it down and run it.
Install the files that must be altered in the "proper" places (Application Data for user-specific files, Program Data for files pertaining to the software as a whole), and then create shortcuts within the main application folder that point to the files in their accessible locations. The legacy app shouldn't know the difference.
EDIT: Here's a method straight out of the custom actions of the installer for an app I wrote that has a similar "legacy" app, which has to read/write data from config files in a subfolder of the app's "home" directory. The IDictionary passed in is the one you get from the various custom action methods (OnBeforeInstall, OnAfterInstall, OnCommit, etc), so you simply drop this into an Installer class, call it from the handler for the install event of your choice (which must be after the installer has made the file system changes), and call it:
private void SetEditablePermissionOnConfigFilesFolder(IDictionary savedState)
{
if (!Context.Parameters.ContainsKey("installpath")) return;
//Get the "home" directory of the application
var path = Path.GetFullPath(Context.Parameters["installpath"]);
//in my case the necessary files are under a ConfigFiles folder;
//you can do something similar with individual files
path = Path.Combine(path, "ConfigFiles");
var dirInfo = new DirectoryInfo(path);
var accessControl = dirInfo.GetAccessControl();
//Give every user of the local machine rights to modify all files
//and subfolders in the directory
var userGroup = new NTAccount("BUILTIN\\Users");
var userIdentityReference = userGroup.Translate(typeof(SecurityIdentifier));
accessControl.SetAccessRule(
new FileSystemAccessRule(userIdentityReference,
FileSystemRights.Modify,
InheritanceFlags.ObjectInherit
| InheritanceFlags.ContainerInherit,
PropagationFlags.None,
AccessControlType.Allow));
//Commit the changes.
dirInfo.SetAccessControl(accessControl);
}
You could manually change the NTFS folder permissions using Windows Explorer to the Application Folder. However, it would be best practice to read/write to a different folder.
Don't write anything to the application folder (under program files). Instead use the user's home folder, or, if you want to write something that's relevant to all users on the machine - ProgramData.
EDIT:
If you can't change your application code, you should still avoid placing program data files under ProgramFiles if you can. There's one other thing you can do. You can create a folder under c:\ProgramData, and just create a symbolic link to it from C:\Program Files... . That way, your legacy application still finds the data where it expects to find it.

Adding Files/Folders to Program Files x86 Folder with C#

I am trying to create a file directory (folder) in the 32 bit Program Files folder to store data that a user will be creating in the program. However, it keeps saying that access is denied when I try to do so. Is there anyway to give the program permission to access the 32 bit program files folder and add subsequent folder and files to it? Here is my code below which is producing a run-time error due to not having permission.
string mainDirectory=Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)+"\\UKC Trial Reporter Files";
if (!Directory.Exists(mainDirectory))
{
Directory.CreateDirectory(mainDirectory);
}
Store your data in Environment.SpecialFolder.ApplicationData, Environment.SpecialFolder.LocalApplicationData or Environment.SpecialFolder.CommonApplicationData (if data have to be accessible by any user).
Never store it in %ProgramFiles%.
%ProgramFiles% is intended for... program files: executables, dlls, app.config files.
In addition of security reasons, there's yet another reason to do this never: when uninstalling, your application's installer must sweep all of files and folders it had created. And this is impossible, when list of files in installdir was changed during application lifetime.
Fortunately, we have UAC since Windows Vista has released.
Don't do that.
Program FIles is exactly that; it should contain EXEs and static resources.
Instead, you need to write to the user's SpecialFolder.ApplicationData folder.

Creating folders inside LocalLow through Installer

I am developing deployment project for Vista. In Vista inside AppData folder there are Local, LocalLow and Roaming folders. What I want from installer is to create folder 'Data' inside LocalLow folder and put there file data.xml (AppData\LocalLow\Data\data.xml). Installer should make this operation for all existing user accounts.
How can I achieve this?
This is a screenshot of setup project('Data' folder configuration) which is not working:
Attached example creates the following path: \AppData\Roaming\LocalLow\Data\data.xml
I think a much better approach is to store the xml file in the application's install directory, then, when the application starts up, copy the file to the appropriate directory.
The primary issue is this: what if a user that wasn't on the machine when it was installed launches the application?
Since your installer didn't copy the file to their directory (because it didn't exist), your application would either have to do something or fail anyway.

C# vista does not giving access to create folder

In my project I have to create some files and directories into my app folder which is into program files. But in vista it is giving me error that I dont have access to create file.
What should I do now for giving access ? Also it not let me access the registry !!
The program folder is not the place to store application data. There is an %APPDATA% folder for that - you are supposed to store your data there.
Use System.Environment.SpecialFolder and System.Environment.GetFolderPath to obtain the path leading to the correct directory.
Also, you need to differentiate between just creating a folder and putting some files in there (for example during installation) or writing to the program folder at runtime, while typically running under a limited account.
The reason for this difference is simply that installation routines and setups run with elevated privileges under Vista / Windows 7, thus those are allowed to create folders and files there. Still, those files are not supposed to be written to at runtime of your application.
So, what is it you want to do? Write data at runtime, or put some files (i.e. dependencies) in your application folder at a single time? If it's the first, comply with the rules and use the %APPDATA% folder. If it's the second, create an installer / setup routine.
Vista and Win 7 have the Program Files folder locked down so you can't write to it with a basic user account. If you need to create folders there, then you should do it in the installer. Otherwise you can use the user's Application Data folder in their profile.
The only other way is to modify the permissions on the installation folder at install time.
Can you turn the UAC off? Or Login as administrator? The chances are that you are creating the folder in the wrong place.

Categories

Resources