I want to save my Files in a more generic way than on Desktop.
So i want to create my own Subfolder in Programs Folder, which i can use to save my stuff.
But i get "System.UnauthorizedAccessException" if i try to create a File using File.AppendAllText(#"C:\Program Files\MySubfolder\MyFile.txt,someString);
I even disabled the Protection of the Folders manually.
My App is not yet compiled so i cant run it as administrator, can i?
How does every Program use this Folder but i cant?
Do i need to compile my App everytime i make a small change and want to test it?
I would really apreciate Help since im stuck with that multiple hours now
It is a very bad practice to try to write in Program Files. This folder as well as other sensitive folders are protected by the OS to prevent malicious code hide between your programs or to prevent unsavy users from messing on the installed programs.
If you want to write your private stuff on your disk you can use these folders
string folder = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
string myFolder = Path.Combine(folder, "MyReservedPath");
Directory.CreateDirectory(myFolder); // if exists does nothing
string myFile = Path.Combine(myFolder, "MyPrivateData.txt");
File.WriteAllText(myFile, dataToWriteOnDisk);
The CommonApplicationData resolves to C:\programdata and this place is usually used to store information needed by your program for any user that uses it.
If you want to store some data that your program produces then it is better to use the
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
There are many other places available, just look at the Environment.SpecialFolder enum.
This code will give you a list of everything mapped to the actual folders in your system
foreach (Environment.SpecialFolder x in Enum.GetValues(typeof(Environment.SpecialFolder)))
Console.WriteLine($"{x} = {Environment.GetFolderPath(x)}");
Related
this is a very simple issue.
Note: I am sure people have found and posted this same issue somewhere but I can't figure out the correct search terms to find it.
Okay, so here is my issue.
Let's say my program is stored at C:\Program Files (x86)\MyProgram\Program.exe.
Now in the program, it basically does
Directory.CreateDirectory(Application.StartUpPath + "\\Files")
So basically, this would create a directory called Files in the same folder as the program itself.
Assume that I have to create the folder in that location, so using a different location is not an option.
So the real problem is, if its located in the c:\Program Files directory, my program gets "access denied" when I try to create the folder.
So how can I get something like this to work without forcing the user to run it as an admin?
If it's in Windows 7, if UAC is elevate, you won't be able to modify anything in c:\Program Files without rooting yourself via 'run as administrator'.
And since windows is a multi-user operating system, storing anything user-specific there is a recipe for disaster.
The right place for your program to put its data is in the appropriate special folder, which you can get/create via either
// user-specific application data is stored here
string userSpecificAppDataDirectory = Environment.GetFolderPath(
SpecialFolder.ApplicationData ,
SpecialFolderOption.Create
) ;
// application data common to all users is stored here
string commonAppDataDirectory = Environment.GetFolderPath(
SpecialFolder.CommonApplicationData ,
SpecialFolderOption.Create
) ;
or one of the other Environment.GetFolderPath() overloads.
In modern operating system the folder C:\program files (x86) is write protected by the OS. You can't create sub folders here without using an administrative account (and also in that case you will be asked to confirm this action unless you disable UAC). So the correct way to follow is to create your data folder in another place. The best option is the CommonApplicationData folder extracted using:
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
or the SpecialFolder.ApplicationData enum if your data should be differentiated by the current user of the application, or the SpecialFolder.MyDocuments if these files are produced by your user and need to be opened freely by other programs (or need to be included in a backup)
After you get the special folder provided by the OS to store application data remember to create a subfolder for your application and the other subfolders as required by your requirements
// In Win7 this usually resolves to C:\ProgramData, but do not use this folder
string appCommon = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
// This resolves to C:\programdata\your_app_name\files
string appData = Path.Combine(appCommon, "your_app_name", "files");
// This will create all directories in the specified path one by one....
if(!Directory.Exists(appData)) Directory.CreateDirectory(appData);
You could try creating any files or folders you need during your installation procedure. I am not sure what success you would find if using a third party install creator, but my understanding is that items added via the Application Files... button in the Publish tab of the Project Properties section in Visual Studio then have access privileges kind of inherently granted for use by the application.
i made a program that uses a pre-made text file that hold a list of sites.
now in some computer the program works fine but, in my friend computer it doesn't.
i check the program on 2 of my windows 7 computers, and 1 xp and i don't have any errors.
this program was used for some time on XP, now my friend want to install it in his windows 7 computer at home, but the program doesn't find the file after he install the program.
this is the error he get:
System.IO.FileNotFoundException: file not found 'C:\Users\eli\AppData\Roaming\fourmlinks.txt'.
file name: 'C:\Users\eli\AppData\Roaming\fourmlinks.txt'
the thing is that i ship the this file in main program folder (Application Files), and it still cant find it.
this is the code i use to find the file when the program starts:
sring path = "";
path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\fourmlinks.txt";
System.OperatingSystem osInfo = System.Environment.OSVersion;
if (osInfo.Platform == PlatformID.Win32NT)
{
if (osInfo.Version.Major == 5 && osInfo.Version.Minor != 0)
{
//running XP
//path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\fourmlinks.txt";
path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\fourmlinks.txt";
}
}
you can see, that i tried to make sure it will work on windows 7 and, windows xp.
NOTE:
i don't mind changing the way i work with this file, or even loss this way and try completely different way that will work on the OS's (win 7 and XP). if u suggest me new way, i will be glad to give a try out.
my questions:
how is it possible that the program works in some computer and in some not?
will you put the file in a different place other then the program folder?
(sorry for my English)
How is it possible that the program works in some computer and in some not?
Because the program depends on something specific to a computer, and this something is different between the two computers. For example, your error message says:
file not found 'C:\Users\eli\AppData\Roaming\fourmlinks.txt'
The program is looking for a file in the Users folder; that is specific to every user on every machine, different users and different machines will have different files.
will you put the file in a different place other then the program folder
Will I? No, I can't because I'm not that user on that machine. If you mean "can my program put the file in a different place ..." then yes, it can.
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "fourmlinks.txt");
That will get a path to the logged-on user's private application data. If you have the "fourmlinks.txt" file in this folder on your machine but someone else doesn't have this file on their machine, then that will work on your machine but not on someone else's, as you asked.
string path = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location),
"fourmlinks.txt");
That will get the path to the installed file. If both you and someone else install the program, then both you and someone else will have the file. If either of you change the file, then the other gets the changes.
So should you always use GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)? Well, that depends. GetExecutingAssembly().Location is typically a place standard users cannot write to, only read from. If you want users to only read and never write to your data, then that is a good place to put it. If you don't, then it isn't.
If you want to create a new file for users to write to and to read from, then write to Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData). If you want to install some starting data with your application but allow the user to change it, then you should include the starting data file in your application. It will get installed to System.Reflection.Assembly.GetExecutingAssembly().Location. Then your application should do something like:
string fileName = "fourmlinks.txt";
string target = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), fileName);
if (!File.Exists(target))
{
string source = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), fileName);
File.Copy(source, target);
}
Another important difference between GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) and Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) is that the former is part of your installer packages; if the user uninstalls or updates your application all their runtime changes will be deleted.
If you want each user to have their own private data that does not get deleted when the application is modified, then you want to use Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData).
I am new to C# and I have made a simple Windows Forms Application that basically updates the persons files for a game.
They have to manually move and delete certain folders just to change version every time. I have successfully accomplished this.
However before I start giving it out I really should improve it. I know I need to change the name of the processes and remove my descriptions ETC.
I have stumbled onto an error and instead of me taking a guess I think it is best to get an opinion from a more experienced person about how to do this.
I am going to use Inno Setup to make the installer for my application, this way I can be sure it will go into their program files 32 and 64 bit. So I know this will be in program files.
So now I am wondering if I have done this the correct way or not? I was using this format to find their program files:
string programFilesFolder = Environment.GetEnvironmentVariable("PROGRAMFILES(X86)") ?? Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
However, would this work on all windows systems(XP, Vista, Win7, Win8) and is it completely accurate? I was going to use the above, and then use this:
string PATCHSELECTOR = Path.Combine(programFiles, #"PATCH SELECTOR");
if (Directory.Exists(PATCHSELECTOR))
{
string GamereliteFolder = Path.Combine(programFiles, #"GAMERELITE~1");
if (Directory.Exists(GamereliteFolder))
And then I move the files using the string method. If the file exists it is deleted before I copy the file over from PATCH SELECTOR to GAMERELITE.
Also will windows XP support using the .exe with an assembly resource embedded which is making the program need to be ran as administrator? I previously was making the assembly work through UAC however that wouldnt always work if they have UAC off or if it is XP so I thought I would try the admin assembly instead.
Can anyone possibly give me some insight, ideas or links?
For executables (not sure for websites & web application) this returns the directory where the executable lives (it's actually the base path where the framework will probe for Assemblies to load, 99% of the the that's the same thing).
System.AppDomain.CurrentDomain.BaseDirectory
This method works for any executable located in a folder which is defined in the windows PATH variable:
private string LocateEXE(String fileName)
{
string path = Environment.GetEnvironmentVariable("path");
string[] folders = path.Split(';');
foreach (var folder in folders)
{
if (File.Exists(Path.Combine(folder, fileName)))
{
return Path.Combine(folder, fileName);
}
}
return String.Empty;
}
Usage:
string pathToEXE = LocateEXE("Example.exe");
Reference:
how to find the execution path of a installed software
How can I get another application's installation path programmatically?
Couple things:
Among the already stated answers, Assembly.GetExecutingAssembly().Location will also give you the full file path of the currently "executing" Assembly. (Alternatively, GetCurrentAssembly)
If I'm reading your question correctly, you're trying to find both your own location as well as another application's. I would highly recommend seeing if the other application has a registry key that specifies the exact location - it'll make your copy step WAY more stable.
I have a C# app that creates a settings file for itself to store the current state of certain visual elements. This app works just fine on any machine that isn't running Windows 7, but on those machines we get an error that the settings file can't be created because the user doesn't have permission. Now, I could fix this issue by going to each computer, logging in as the administrator and giving the user read and write access on the program folder for the application that we've installed, but there has to be a better way.
It seems like in XP, you got write access on the folders you created by default, but that isn't the case anymore. Is there a setting I need in the setup package to make this work?
The point is that you shouldn't be storing settings files in the program folder. Microsoft have advised against this for a long time, but started making things stricter with Vista IIRC.
Use Environment.SpecialFolders.ApplicationData (etc) to find the most appropriate place to put settings. Or use the .NET settings infrastructure which does this automatically for you.
are you trying to create files in the installation folder? you should be using the user data folder for data and not the installation folders. Use the Environment.SpecialFolders.ApplicationData folder to get a folder you can write to.
You're probably running as an administrator on your non-Windows 7 machine which an write anywhere. Be sure to save any per user instance data in their AppData folder (roaming if it should follow them from computer to computer, or local if its a cache or local to taht machine only). If you need to share settings between users, use the C:\ProgramData folder with the appropriate permissions.
A program shouldn't try to store settings in its installation directory.
Be sure to use the SpecialFolders along with Environment.GetFolderPath to get the right locations needed. You should never hard code paths because they can be different between versions AND languages. (I know in the German version of XP it wasn't Program Files but Programme!)
this app works just fine on any machine that isn't running Windows 7
Wrong! It only works on those machines if you run as administrator. I think you'll find your program is broken on Windows XP as well if you try to run it on just about any business computer rather than a home computer.
Instead, this kind of information needs to go in one of the special Application Data folders.
This is a security flaw in your program because your program is writing information to the program directory (which is, and should be, protected.) If it's a situation of correcting the root cause, consider using the SpecialFolder enumeration or the static members on Application like like CommonAppDataPath to write your information to a more appropriate location.
Assuming the typical approach to writing a file via a path, this is a trivial fix and there's no good "expediency" reason to not correct the root cause. If you're not sure about how to manipulate the path, consider using Path.Combine(). It does it for you.
In general, you shouldn't be writing program data to any folder underneath Program Files (even if you created the folder). You should use the Environment.GetFolderPath(...) to figure out where to put your application specific data. You can pass in one of many enums defined here -- you probably want Environtment.SpecialFolder.CommonApplicationData
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
I do not see how any of this is an actaul answer. I need to be able to write a report and have it saved the users documents folder the same folder I used to read the xml files I am writing the report from.
I created a program in C# .net using VS2008.
When the user installs the program I don't know if it will be on the C: drive or D: drive or someplace else. The issue is that I need the program to automatically create files and then retrieve those files later on without any assistance from the user.
I thought the least complex situation was to place these files in the directory where the program is installed so that the location would remain constant and this strategy would reduce the chances that the files will be accidentally deleted by the user.
Question 1:
How to I refer to the install directory of my app when the user has their choice of the install location?
Question 2:
Should I even be doing it this way or should I be looking at this from a totally different perspective.
Assembly.GetExecutingAssembly().Location will give you the path to the currently executing assembly.
However, writing to that location will cause problems for users running on Vista, Server 2008 and later, which are more strict about normal users not writing to places like C:\Program Files. Your best bet is probably something like:
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
There are a bunch of options for Environment.SpecialFolder, based on what exactly you want to store.
Sounds like a perfect solution for the Isolated Storage function in .Net (System.IO.IsolatedStorage).
You access via objects and the path is controlled by .Net. It stores the items in the local settings\application data\isolated storage for each log in.
You can use the System.Environment.CurrentDirectory property to determine where your application belongs.
Alternatively, you could look into isolated storage. The data is stored on a user/machine basis (as you choose) so you can store different files for different users.
Which you choose depends on how much information you want to store, and the security surrounding it.
You can get the current directory using:
string dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
This is a valid and useful way of storing files related to your .exe - you can always navigate using relative directories from where your executable is running from, meaning you don't need to worry about where it's installed.
Alternately, if you'd like your .exe to be freely copyable to any directory, you could consider storing your data in a well known location, like the user's Application Settings directory in their user profile (for windows).
Application.StartupPath should do that for you or:
private static string GetApplicationPath()
{
return System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
}
How to get the path of app(without app.exe)?