Adding Files/Folders to Program Files x86 Folder with C# - 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.

Related

How to access permission to files after installation?

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.

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

Self Deleting Executable (Uninstaller)

I'm trying to make an uninstaller.
I basically need to be able to remove a directory in the program files that contains the uninstaller.
I was thinking to have the uninstaller create a copy of itself to the temp folder,
then have the uninstaller running from the program folder open the uninstaller in temp and close itself where it continues the uninstall.
Problem is, how do I delete the uninstaller in the temp folder...
Check out: https://www.catch22.net/tuts/win32/self-deleting-executables
He has multiple solutions - but mostly aimed at C++ code.
I am currently trying to implement the "DELETE_ON_CLOSE" method in C#.
A comment to all the nay-sayers: MSI does not solve this problem in all cases. In my case, my application needs to install to a network folder, where any network user can run the app. It also needs to support upgrades and uninstalls from any network workstation - not necessarily the same workstation that installed the app. This means I cannot register an Uninstaller into the Add/Remove Programs list on the local machine. I must create an Uninstall.exe that is dropped into the install folder. MSI does not support that, so I have to write my own.
Even though I agree with everyone saying you shouldn't do that, what you can do is:
Have your program create an executable (and config file) in the temporary folder of the OS it's working on.
Have your program start it as an independent process, then exit.
That executable then calls back the actual setup stuff.
Once the setup is done, the temporary executable can delete the setup files.
Since the only trace of your program is now in the temp folder, it will eventually get cleared automatically.

File redirection from Program data to AppData\Local\VirtualStore\ProgramData

I am using C# with .net 3.5
I am saving my program data in a file under: C:\Program Data\MyProgramName\fileName.xml
After installing and running my application one time I uninstalled it (during uninstallation I'm removing all the files from "program data")
and then I reinstall the application, and ran it.
The strange thig is that my application started as if the files in program data existed - means, I had old data in my app even though the data file was deleted.
When running:
File.Exists("C:\Program Data\MyProgramName\fileName.xml")
I got "true" even though I knew for sure that the file does not exist.
The thing became stranger when I ran the application as admin and then the file didn't exist.
After a research, I found out that when running my application with no admin priviliges instead of getting: "C:\Program Data\MyProgramName\fileName.xml" I get "C:\Users\userName\AppData\Local\VirtualStore\ProgramData\MyProgramName\fileName.xml"
and indeed there was a file that existed from the previous installation (that I obviously didn't delete ,because I didn't know it existed).
So apparentlly there is some virtual path to the file under program data.
EDIT :
I found out that after deleting the old file in the virtual store, my application is suddenly able to find the correct file. (I didn't make any changes in the file under Program Data.
My question is:
why is it happen.
How can I prevent it from happening
Thanks in advance
Do you actually have to write to the per-system Program Data folder instead of the per-user Application Data folder(s)?
You might want to take a look at Environment.GetFolderPath and the following Environment.SpecialFolders:
Environment.SpecialFolder.ApplicationData - data folder for application data, synchronized onto domain controller if the user profile is roaming
Environment.SpecialFolder.LocalApplicationData - data folder for application data, local and not synchronized (useful for, for instance, caches)
EDIT:
Tested on Windows 7 x64, non-administrator user.
var appData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
var myFolder = Path.Combine(appData, "MyApp");
if(!Directory.Exists(myFolder)) Directory.CreateDirectory(myFolder);
File.WriteAllText(Path.Combine(myFolder, "Test.txt"), "Test.");
This does what is expected, ie. writes into C:\ProgramData\MyApp\Test.txt. As far as I can tell (Administrator mode Command Prompt), there's no UAC virtualization going on either.
Double edit:
I guess what's happened is that at some point an Administrator user has written the files into your ProgramData folder, and as such, UAC file system virtualization kicks in and redirects the non-administrator writes into the VirtualStore.
Does your uninstaller run as Administrator? If it does, you might have to check both the VirtualStore path for the user who initiates the uninstall, and the actual file system path for program data to remove. I'm not sure if there's an official way to do this, though...
I found the reason for the bug.
the application is trying to take ownership on the file and then the other file is created.
I removed that line and now everything works just fine.

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