C# - Copy a file to user folder - c#

I'm making the GUI program that users can decompile/recompile an APK file but compiling won't work correctly becuase the framework file is missing. I'm making the simple framework installer that must be installed on user folder (for apktool.jar). Instead using the path that only works on my computer. i want to make it work for all users.
here is the code i made
File.Copy(#"do-not-touch\1.apk", #"C:\Users\quoc\apktool\framework\1.apk");

You can use the Environment.SpecialFolder Enumeration to get the path like so:
var userDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
Note: Please use ApplicationData and not the root profile, it's rude to fill the user's toplevel profile with stuff.

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.

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.

Store path to directory in C# library

It's more "architecture" then "language" question.
I have a class library in my .Net solution, that generates something using images from a directory that is deployed with the application. User has to be able add new images easily, so I can't put them to resources.
This directory is attached to this class library. Is there any way to get its path? AppDomain.CurrentDomain.BaseDirectory for debug returns /bin/debug/, that isn't right of course.
i.e. - my application is installed to C:\Program Files\MyApp. So, path has to be "C:\Program Files\MyApp\ImagesLib".
BUT:
my application is downloaded from subversion and saved to d:\my projects\MyApp. So, path has to be "d:\My Projects\MyApp\ImagesLib".
How to make this path universal? The directory is created from Visual Studio (right click/Add/New Folder)
I think your architecture needs a rethink.
In the new UAC world you're expected to write to specific locations on a per user or per computer basis. If you install to Program Files for example, under UAC trying to write to your install folder may fail (depending on privileges).
Because of this you will need to use Environment.GetSpecialFolder() coupled with the SpecialFolder enum.
You can read more about these here:
http://msdn.microsoft.com/en-us/library/14tx8hby.aspx
http://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx
For example, assuming you just want to store on a per computer basis:
var base_data_folder = Environment.GetSpecialFolder(SpecialFolder.CommonApplicationData);
var data_folder = Path.Combine(base_data_folder,"MyApplication");
var images_folder = Path.Combine(data_folder,"Images");
On my Windows 7 machine this would equate to:
C:\ProgramData\MyApplication\Images

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.

use correct path of folder in win app

I write a win app,now i want to make setup for my app project.i have a folder in the
root path of my project and it contains some wave files that i use theire path
in my app like: "F:\test\Resources\1.wav".
now my queistion is: how can i use their path in correct format ,that if i install setup file,on
another computer my app works true ,only because of the path of the wave files.
thanks alot for your attention.
You can get your EXE's path by calling System.Reflection.Assembly.GetExecutingAssembly().Location.
Alternatively you could store you install path in the registry somewhere with the installer and then you can check that registry entry.
You can useApplication.StartupPath, and append your subfolder.
So something like Application.StartupPath + #"\Resources\1.wav" should do the trick.
This is without Reflection, so I guess it will be a little faster, but I haven't benchmarked it.

Categories

Resources