How to copy file to the C:\Program Files (x86)\ - c#

I can copy files to the C:\Program Files (x86)\... ...but only with the administrator account.
This file is a configuration file like App.Config, but with a different name, and I want to put it into the application path's sub folder.
The scenario is like following.
Put the initial configuration file in the \Cfg\org.cfg
When start application program,myApp.exe, check if configuration file exists in the application path.
If it doesn't exist, copy org.cfg to the myApp.exe.config and load it.
I tried DirectoryInfo.SetAccessControl() but following error occur as well.
"Attempted to perform an unauthorized operation"

Program Files (x86) required administrative permission to write to. So does changing the permissions, which is why SetAccessControl fails. There's really no way around that. If you want to have your configuration file writable by the application, then you might consider changing the permission of the configuration file during installation of the program when you do have administrative access.
I would instead however recommend putting your configuration file somewhere in the user's profile, which is writable by default for all users, like in %LOCALAPPDATA%.
You can load configuration files from arbitrary locations as well, it doesn't have to be in the .config file next to the executable. For an example of that, look at this question.

Related

C# Move AppSettings from .exe.config in Program Folder to Custom Location

C# MVVM project targeting .NET Framework 4.6.2 with underlying SQL Server database.
We have a handful of user-writable settings in appSettings. These are stored in the PROGRAMNAME.exe.config in C:\Program Files\PROGRAMNAME
The problem is that our users typically do not have write permissions to the C:\Program Files\PROGRAMNAME directory and so cannot write changes to this file. The program either needs to be run as an administrator or we need to give write permissions to that directory. Neither is ideal.
I was under the impression that it should create a copy of the .exe.config in C:\Users\USERNAME\AppData\Local\VirtualStore\Program Files\PROGRAMNAME but this does not seem to happen, especially in our Citrix environments.
Is there a way to relocate these specific appSettings to a file in a user-writable location?
You can do it. Read the config file like this:
Configuration App_Config =
ConfigurationManager.OpenExeConfiguration("C:\Temp\PROGRAMNAME.exe");
By this, it will look for the config file PROGRAMNAME.exe.config in the specified path C:\Temp
Please notice the path is not specified as C:\Temp\PROGRAMNAME.exe.config
Get more info from Here

Can access private file in localhost, but not in production

I'm writing an ASP.NET Core app, and I'm trying to use a file's path without exposing it to the web. I set it to copy to output directory, so it loads when I test it on localhost, but it gives me an error when published to the web:
The system cannot find the file specified.
This is the code that generates the path:
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config", "filename.p12");
I've also tried
Path.Combine(Environment.CurrentDirectory, "Config", "filename.p12");
I'm guessing AppDomain.CurrentDomain.BaseDirectory and Environment.CurrentDirectory point to a different location when published? Or filename.p12's 'Copy to Output Directory' property doesn't carry over to the published version?
EDIT:
I also tried:
Path.Combine(environment.ContentRootPath, "Config", "file.p12");
Where environment is an IHostEnvironment, to the same effect. I'm getting the feeling that the file isn't being copied over into the published version. So, I changed the filename I put in this question to be file.p12 instead of file.txt, which is what I originally put it as, in case it doesn't copy over that type of file for security reasons.
The error said The system cannot find the file specified., but the file was actually there. I was actually missing the X509KeyStorageFlags.MachineKeySet flag when I read the .p12 file. I think the reason it didn't work in production was that the server's current user didn't own the file, so I needed to specify that the machine owns it with that flag.

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

Configuration.Save operation not working for some machine

I have a C# executable reading and updating it's configuration file (app.exe.config) at runtime, specifically, the "appSettings" section. After I make two changes to two key values and save them using the Configuration.Save() method, an "access to the path" error is thrown, but only on some users' machines (so far 2 reports out of 10,000). We have never seen this issue in-house, only in production.
The Configuration.Save() method seems to be the issue based on our program's log file. When a problem with this call happens a "ConfigurationErrorsException" occurs because the configuration file could not be written to -or- the configuration file has changed. The configuration file is in the same directory as the application. This is a Dot Net 4 application running on a Windows 7 PC.
The code is:
Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
configuration.AppSettings.Settings["Last Updated Package"].Value = packageVersion;
configuration.AppSettings.Settings["Copy Updated Files"].Value = bool.TrueString;
configuration.Save(ConfigurationSaveMode.Minimal);
ConfigurationManager.RefreshSection("appSettings");
The error is:
An error occurred loading a configuration file: Acces to the path 'C:\Program Files (x86)\My Program\bin\guaixcax.tmp' is denied. (C:\Program Files (x86)\My Program\bin\MyProgram.exe.Config)
Is this a permissions issue, or can I add something to either the code or config file to fix this issue?
I have had similar issues with .NET program installations. It has always been a permissions issue. To test if this is your problem, you should try running your application as an unprivileged user - developers tend to have administrator rights...whenever they can manage it.
If it fails, edit the security of the config file (as an administrator) to allow the "Users" group write access to your "bin" folder, and try it again. If it works, you've identified the problem. Then you can figure out what the best solution is. Some options would be:
Set access rights to necessary files/folders from your installer to work for the users that will run the application
Run the application as a user with admin rights (NOT a good idea from a security best-practices point of view)
Instead of modifying the main app settings file, create a separate settings section referencing a file that has the data that can be changed:
<configuration>
<configSections>
...
<section name="MyChangableSettings" type="My.Namespace, ChangableSettingsClass"/>
</configSection>
...
<MyChangableSettings configSource="Path\To\Writable\StorageDir\mySettings.config"/>
</configuration>

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.

Categories

Resources