Converting absolute path to relative path C# [duplicate] - c#

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Getting path relative to the current working directory?
I have code in C# that includes some images from an absolute path to a relative so the image can be found no matter where the application fold is located.
For example the path in my code (and in my laptop for the image) is
C:/something/res/images/image1.jpeg
and I want the path in my code to be
..../images/image1.jpeg
So it can run wherever the folder is put, whatever the name of the C: partition is etc.
I want to have a path in my code which is independant of the application folder location or if it is in another partition, as long as it is in the same folder as the the rest of the solution.
I have this code:
try
{
File.Delete("C:/JPD/SCRAT/Desktop/Project/Resources/images/image1.jpeg");
}
catch (Exception)
{
MessageBox.Show("File not found:C:/Users/JPD/Desktop/Project/images/image1.jpeg");
}
This code only runs if the file and folder are in that certain path, (which is also the location of the code) I wish for that path to be relative so wherever I put the whole folder (code, files etc) the program will still work as long as the code (which is under project folder) is at the same location with the folder images... what should I do?

Relative paths are based from the binary file from which your application is running. By default, your binary files will be outputted in the [directory of your .csproj]/bin/debug. So let's say you wanted to create your images folder at the same level as your .csproj. Then you could access your images using the relative path "../../images/someImage.jpg".
To get a better feel for this, try out the following as a test:
1) create a new visual studio sample project,
2) create an images folder at the same level as the .csproj
3) put some files in the images folder
4) put this sample code in your main method -
static void Main(string[] args)
{
Console.WriteLine(Directory.GetCurrentDirectory());
foreach (string s in Directory.EnumerateFiles("../../images/"))
{
Console.WriteLine(s);
}
Console.ReadLine(); // Just to keep the console from disappearing.
}
You should see the relative paths of all the files you placed in step (3).

see: Getting path relative to the current working directory?
Uri uri1 = new Uri(#"c:\foo\bar\blop\blap");
Uri uri2 = new Uri(#"c:\foo\bar\");
string relativePath = uri2.MakeRelativeUri(uri1).ToString();

Depending on the set up of your program, you might be able to simply use a relative path by skipping a part of the full path string. It's not braggable, so J. Skit might be up my shiny for it but I'm getting the impression that you simply want to make it work. Beauty being a later concern.
String absolutePath = #"c:\beep\boop\HereWeStart\hopp.gif";
String relativePath = absolutePath.Substring(13);
You could then, if you need/wish, exchange the number 13 (which is an ugly and undesirable approach, still working, though) for a dynamically computed one. For instance (assuming that the directory "HereWeStart", where your relative path is starting, is the first occurrence of that string in absolutePath) you could go as follows.
String absolutePath = #"c:\beep\boop\HereWeStart\hopp.gif";
int relativePathStartIndex = absolutePath.IndexOf("HereWeStart");
String relativePath = absolutePath.Substring(relativePathStartIndex);
Also, your question begs an other question. I'd like to know how you're obtaining the absolute path. Perhaps there's an even more clever way to avoid the hustle all together?
EDIT
You could also try the following approach. Forget the Directory class giving you an absolute path. Go for the relative path straight off. I'm assuming that all the files you're attempting to remove are in the same directory. If not, you'll need to add some more lines but we'll cross that bridge when we get there.
Don't forget to mark an answer as green-checked (or explain what's missing or improvable still).
String
deletableTarget = #"\images\image1.jpeg",
hereWeAre = Environment.CurrentDirectory;
MessageBox.Show("The taget path is:\n" + hereWeAre + deletableTarget);
try
{ File.Delete(hereWeAre + deletableTarget); }
catch (Exception exception)
{ MessageBox.Show(exception.Message); }
Also, please note that I took the liberty of changing your exception handling. While yours is working, it's a better style to rely on the built-in messaging system. That way you'll get more professionally looking error messages. Not that we ever get any errors at run-time, right? ;)

Related

Read text file from relative path within project

I am creating a unit test which works using the following exact path:
string path = #"/Users/{username}/Coding/computershare/ChallengeSampleDataSet1.txt";
I read the text from the file by passing this path
string pricesFromFile = System.IO.File.ReadAllText(path);
However, I do not want to hardcode the complete local file path - I want to use the relative path in the project directory.
Therefore I tried the below using other articles on StackOverflow:
string path = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "ChallengeSampleDataSet1.txt");
But file is not found. How can I fix this so that I'm able to load the file when running the app from another machine?
Edit: the error in console using the second method is
System.IO.FileNotFoundException : Could not find file '/Users/{username}/Coding/computershare/bin/Debug/net5.0/ChallengeSampleDataSet1.txt'.
This should do the trick:
string path = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory + #"..\..\..\", "ChallengeSampleDataSet1.txt");
Note the direction of the slash (\)
Since the error is "/Users/{username}/Coding/computershare/bin/Debug/net5.0/ChallengeSampleDataSet1.txt" it indicates that your base directory is /bin/debug/net5.0 down from the root of the code. By double dotting up three levels, you'll be able to find the file in question.

How do i get right the directory of my application? [duplicate]

This question already has answers here:
How can I get the application's path in a .NET console application?
(30 answers)
Closed 5 years ago.
I've made a small console application (first publish in c#). but i cant use my resource files. I used textfiles can give it. It worked when i used the debug directory
My goal is to create a directory like this:
Applicationmap
+ application.exe
+ setup
resource map
+ configurations.txt
Logger
+ .
Now if i try to reach the configuration file it sends me to:
C:\Users\<username> \AppData\Local\Apps\2.0\D01L7N51.9EW\R7HB7NAB.B7Y
\sele..tion_0000000000000000_0001.0000_92af5262ce6f49d8
While i'm expecting C:/Users/<username>/ Documents/<application>/ + resources/config.txt.
I've tried
string dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
Console.WriteLine(dir);
&&
Path.GetDirectoryName(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
&&
Console.WriteLine(Directory.GetCurrentDirectory());
but i always end up at the appdata map.
You could simply use Application.StartupPath (reference), but the outcome will always depend on where you place/install the executable file
If you always want to point the current user's Documents folder (which is registered as a special folder within the operating system), like in your example, you could either use:
String path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
or (but at your own risk since its much less safe):
String path = Path.Combine(Environment.ExpandEnvironmentVariables("%userprofile%"), "Documents");
Once you have retrieved the correct Documents folder path with either the first or the second approach, combine it with the last part:
path = Path.Combine(path, "resources/config.txt");
For more information concerning the two approaches:
Environment.GetFolderPath
Environment.ExpandEnvironmentVariables
How about:
System.IO.Path.GetDirectoryName(Application.ExecutablePath);

How do I remove version number from file path? - Winforms c#

I am wondering how to remove the version number from a file path in a Windows Form Application.
Currently I wish to save some users application data to a .xml file located in the roaming user profile settings.
To do this I use:
get
{
return Application.UserAppDataPath + "\\FileName.xml";
}
However this returns the following string:
C:\Users\user\AppData\Roaming\folder\subfolder\1.0.0.0\FileName.xml
and I was wondering if there is a non-hack way to remove the version number from the file path so the file path looks like this:
C:\Users\user\AppData\Roaming\folder\subfolder\FileName.xml
Besides parsing the string looking for the last "\", I do not know what to do.
Thanks
Use Directory.GetParent method for this purpose.
get
{
var dir = Directory.GetParent(Application.UserAppDataPath);
return Path.Combine(dir.FullName, "FileName.xml");
}
Also note that I've used Path.Combine instead of concatenating paths, this method helps you to avoid so many problems. Never concatenate strings to create path.

How to copy files from one disk to another location with the same folder structure?

I want to make an exact copy of some files, directories and subdirectories that are on my USB drive I:/ and want them to be in C:/backup (for example)
My USB drive has the following structure:
(just to know, this is an example, my drive has more files, directories and subdirectories)
courses/data_structures/db.sql
games/pc/pc-game.exe
exams/exam01.doc
Well, I am not sure how to start with this but my first idea is to get all the files doing this:
string[] files = Directory.GetFiles("I:");
The next step could be to make a loop and use File.Copy specifying the destination path:
string destinationPath = #"C:/backup";
foreach (string file in files)
{
File.Copy(file, destinationPath + "\\" + Path.GetFileName(file), true);
}
At this point everything works good but not as I wanted cause this doesn't replicate the folder structure. Also some errors happen like the following...
The first one happens because my PC configuration shows hidden files for every folder and my USB has an AUTORUN.INF hidden file that is not hidden anymore and the loop tries to copy it and in the process generates this exception:
Access to the path 'AUTORUN.INF' is denied.
The second one happens when some paths are too long and this generates the following exception:
The specified path, file name, or both are too long. The fully
qualified file name must be less than 260 characters, and the
directory name must be less than 248 characters.
So, I am not sure how to achieve this and validate each posible case of error. I would like to know if there is another way to do this and how (maybe some library) or something more simple like an implemented method with the following structure:
File.CopyDrive(driveLetter, destinationFolder)
(VB.NET answers will be accepted too).
Thanks in advance.
public static void Copy(string src, string dest)
{
// copy all files
foreach (string file in Directory.GetFiles(src))
{
try
{
File.Copy(file, Path.Combine(dest, Path.GetFileName(file)));
}
catch (PathTooLongException)
{
}
// catch any other exception that you want.
// List of possible exceptions here: http://msdn.microsoft.com/en-us/library/c6cfw35a.aspx
}
// go recursive on directories
foreach (string dir in Directory.GetDirectories(src))
{
// First create directory...
// Instead of new DirectoryInfo(dir).Name, you can use any other way to get the dir name,
// but not Path.GetDirectoryName, since it returns full dir name.
string destSubDir = Path.Combine(dest, new DirectoryInfo(dir).Name);
Directory.CreateDirectory(destSubDir);
// and then go recursive
Copy(dir, destSubDir);
}
}
And then you can call it:
Copy(#"I:\", #"C:\Backup");
Didn't have time to test it, but i hope you get the idea...
edit: in the code above, there are no checks like Directory.Exists and such, you might add those if the directory structure of some kind exists at destination path. And if you're trying to create some kind of simple sync app, then it gets a bit harder, as you need to delete or take other action on files/folders that don't exist anymore.
This generally starts with a recursive descent parser. Here is a good example: http://msdn.microsoft.com/en-us/library/bb762914.aspx
You might want to look into the overloaded CopyDirectory Class
CopyDirectory(String, String, UIOption, UICancelOption)
It will recurse through all of the subdirectories.
If you want a standalone application, I have written an application that copies from one selected directory to another, overwriting newer files and adding subdirectories as needed.
Just email me.

What is the difference between an absolute and a relative path?

I am asking because I am working on a project for school. Yes this is homework. But, I'm trying to understand a little bit more, though.
This is one example of what is being asked.
• When the user clicks the “Save” button, write the selected record to the file specified in txtFilePath (absolute path not relative) without truncating the values currently inside.
This is what I have,
private void button2_Click(object sender, EventArgs e)
{
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
StreamWriter myWriter = new StreamWriter(saveFileDialog1.FileName);
myWriter.Write(txtFilePath.Text);
myWriter.Close();
}
}
Now, I don't understand if I am doing this right. I know when I save it to my desktop and I delete it from my listbox and when I try to reload it again nothing shows up. This is what I have on my form,
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
StreamReader myReader = new StreamReader(openFileDialog1.FileName);
txtFilePath.Text = openFileDialog1.FileName;
txtFilePath.Text = myReader.ReadToEnd();
myReader.Close();
}
}
And this is the load,
private void Form1_Load(object sender, EventArgs e)
{
string[] myFiles = Directory.GetFiles("C:\\");
foreach (string filename in myFiles)
{
FileInfo file = new FileInfo(filename);
employeeList.Items.Add(file.Name);
}
//...
Can someone please help me make sense of this?
Say you were giving directions to a spot. You have two methods you can describe getting to the location:
Relative to where you stand,
Relative to a landmark.
Both get you to the same location, but the former doesn't always work ("take a left, then a right, go through two lights then take another right" wouldn't necessarily work from the next town over, but works from where you stand). That's essentially the difference.
If you have C:\Windows\System32, that's an absolute path. If you have Windows\System32, it will only work so long as you're starting from C:\. If you start in C:\Program Files you would need a ..\ to get there correctly.
However, no matter where you are on the hard drive, C:\Windows\System32\ is a definitive way to get to that folder.
It's actually a simple distinction. A relative file path is going to be a structure based around a root node; and an absolute path is going to be a structure based on a non ambiguous location. That sounds kind of wonky, but it's actually pretty simple.
Here are some examples:
Absolute Paths
C:\inetpub\yourapplication\default.aspx
http://www.yourapplication.com/default.aspx
These paths are absolute because they are non ambiguous. Example 1 shows an absolute file path, and example 2 shows an absolute URL.
Relative Paths
./../script/something.js
~/default.aspx
A relative path specifies a location based on some known ahead point of reference. So in example 1, you know to go up one directory, then down into a directory called script, then to a javascript file. In example two, you are specifing the aspx page contained within the root of your application.
So, germane to your specific problem, you want to write a file to a specific absolute path, which means it needs to be a non ambiguous location.
An absolute path is the whole path name required to access the location in the file system.
For example: C:\Program Files\Internet Explorer\iexplorer.exe
Where as a relative path is in relation to some landmark, usually your main executable files location or the 'start in' location set when you open the program.
For example if your main executable is in C:\Program Files\ the relative path to iexplorer.exe is Internet Explorer\iexplorer.exe.
This is done usually when you don't always know where the file will absolutely be, like which drive letter it will be installed in or which folder it will be under.
However for a good example, if your file came with your program and you know your programs installation structure, you can use relative pathing to find all your files no matter where your program is installed as opposed to abolute pathing where your program would need to be installed in the exact same location each time.

Categories