Quick Question: How can I make sure the current directory is not changed because of OpenFileDialog? - c#

say my application is installed in C:\programfiles\xyz\ I've some setting & other data files (*.dat files) in this directory too.
My application uses OpenFileDialog to open an image. Problem is that when ever user browses to some directory (say MyPictures) for an image. The current working directory of the application becomes that directory (MyPictures in this case).
After user inputs the image. I do some processing over it and save some values to imagedata.dat which will be located in the path where original application is installed.(C:\programfiles\xyz here )
In my code I'm just using FileStream("imagedata.dat",...,...) without any path prefix before the filename. Problem here is that application is crashing because it is searching for imagedata.dat in 'MyPictures\imagedata.dat'.
How can I avoid this?

You should be using absolute path names when saving data to files. The current working directory is controlled by the user, not by you (for example, if they launch your process from a shortcut then the working directory could've been changed before your process even starts up).
Also, you should never save anything under C:\Program Files during normal use. Doing this means your program needs to be running as an administrator, and unless you're doing administrator-y things then you should be able to run it as a regular user.
The correct thing to do in your case is to use the Environment.GetFolderPath() function to get the location of the ApplicationData folder and save your data under there. Just choose a sub-directory based on your application's name.

You could save it to GetCurrentDirectory then restore with SetCurrentDirectory. However, I agree wih codeka that using the appropriate GetFolderPath (probably ApplicationData, CommonApplicationData or LocalApplicationData) is a better solution.

Related

File path for c# when moved to a memory stick

sorry first time user and currently learning c# at uni, i'm working on an assignment and i'm trying to get the file path to work on the memory stick as that's what i need to hand it in on, thanks many regards
I'm not completely sure what your question is by I think what you're talking about is absolute vs relative paths. If you use an absolute path like "C:\users\yourname\blalba\project\stuff", then it's obviously only going to only work on your computer. However, you mostly all of the time want to use relative paths. Relative paths have the root directory of the build output files for your project; where your .exe file is built for your project. This is usually in "projectdir\bin\debug" or "projectdir\bin\release". So if you put for example a file called 'test.txt' in that directory, you can simply put the relative path "test.txt" instead of "C:\users\yourname\blalba\project\bin\debug\test.txt". If you were to put 'test.txt' in the project directory, you can use the relative path "....\test.txt". "..\" means navigating one step back.
The path to the directory containing the files you are looking for is "F:\Mod005244, 1715840". The "1715840 JH" is just the name of the drive. You access different drives via the drive letter. In this case, the drive letter "F" was assigned to your flash drive.
I would suggest making the file path configurable or request input from the user of the program as the drive letter of a flash drive will not always be "F". There are even classes (such as FileBrowserDialog) that will open a graphical file browser dialog and prompt the user to navigate and select a file.

C# Listing all directories in C:\

In my application every user can set his own save path to save his files and settings
so every time the user log in i must search a folder that contains the username+"Data"
for example if the user name was "Kim" i need to find the path to the folder KimData
when i try to get all directories in C:\ the UnauthorizedAcessException appears
so is there a way to search for that folder or just skip the unauthorized folders while searching ?
The UnauthorizedAccessExpection means that the caller does not have the required permission to access the directory/file. Since you're doing it locally, there are several options. After you attempt to copy the data from VS to the data in the file (Create, copy, delete) etc.... you can try File.SetAttributes(yourfile, FileAttributes.Normal).
You can also use Environment.GetFolderPath. Accordingly, this:
"Gets the path to the system special folder that is identified by the
specified enumeration, and uses a specified option for accessing
special folders."
Also, I'm guessing you're simply looking through the entire directory/folder/path all at once. A workaround would be to probe one directory at a time. This is assuming you are adding a file. Once you've found your directory, you can use:
Directory.GetFiles(path)
.ToList()
.ForEach(s => files.Add(s));
Directory.GetDirectories(path)
.ToList()
.ForEach(s => AddFiles(s, files));
EDIT: Some helpful related questions on stack to look at might be:
UnauthorizedAccessException
Directory.GetFiles
Take a look at Ignore folders/files when Directory.GetFiles() is denied access and see if it helps you.
However if you are trying to look for a specific folder - which according to your question the user can place anywhere - in the entire directory tree i advise against it as it probably will be slow.
I would recommend saving the path somewhere and reading it from there when the user logs back on.
If its a desktop app and each user runs the app with its own windows account an even better solution would be to always write the data to the user's ApplicationData folder which you can get with Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData).
As the name indicates this folder exists to keep applications data and its individual for the user logged in to windows

Get a file path C#

I have a .txt file that I need to read in my program. For the moment I have the directory hardcoded as such:
file = new StreamReader(#"C:\Users\<username>\Documents\File.txt");
However that will (obviously) not work on any other PC that does not have that access to altering the code, or (by some strange happenstance) the same directory as the original code.
How can I get the full file path to set it in my program using C#?
You could create the file in their Application Data directory (they could still find it if they wanted to, but at least it wouldn't be as obvious as the My Documents folder).
When you want to access it, use the Environment class. There are methods for locating special folders for the current user, without resorting to hard-coded paths:
var filePath = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData), "File.txt");
Option 1:
Application.StartupPath can be used for the purpose.
It gets the path for the executable file that started the application, not including the executable name.
Keep File.txt with your executable.
Option 2:
Use Environment.SpecialFolder.ApplicationData
It gives directory that serves as a common repository for application-specific data for the current roaming user.
NOTE: If you want to restrict the user to look into the contents of File.txt then you might need to encrypt the contents.

Get access to program's own directory

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.

Using WritePrivateProfileString to write path issue

I am using WritePrivateProfileString in c# (through DllImport) to store paths taken from textboxes on the interface. And the .ini file name is hardcoded in my application
string ini_file = ".\\config.ini";
However, when the file writing happens, the configuration file is written to the first path taken from the interface instead of writing it to the exe directory. Which is quite odd.
Debugging shows that the values are sent correctly to the WritePrivateProfileString but it still is written to the wrong location. Anyone knows why is that happenening?
I'd guess that something is changing the working directory of your process, most likely your code in the process. Note that the documentation has this to say:
If the lpFileName parameter does not contain a full path and file name for the file, WritePrivateProfileString searches the Windows directory for the file. If the file does not exist, this function creates the file in the Windows directory.
Now my guess is that this applies if you supply just a file name. Because your file name starts with . I believe that will force the function to start from the current working directory.
Having said all of that, and no matter what the cause of the problem is, you should use a fully-qualified path in order to make sure the file is written where you want it to be written. Whenever you want the file to go in a specific directory, it's always easiest to force that by using fully-qualified paths.
You can find the path to your executable using Application.ExecutablePath and then remove the file name part.
Another point to make is that the same directory as the executable may be a bad choice. If your program is installed under the Program Files directory then the directory which contains the executable will not be generally writeable. I think you should consider using a directory under in the user profile. Look for one of the Environment.SpecialFolder values.
Further to David Heffernan's answer - you can use
Path.GetDirectoryName(Application.ExecutablePath);
to safely get just the running application's folder part.
If you're in a dll rather than an executable, you can use
Path.GetDirectoryName(Assembly.GetAssembly(typeof(MyClass)).CodeBase);
Both require System.IO, and were originally posted here. Second example also requires System.Reflection).
Application data files are supposed to be written to the LocalApplicationData special folder.
string path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData);
You typically will not have permissions to write into the Program Files folder etc.

Categories