10

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?

John Demetriou
  • 4,093
  • 6
  • 52
  • 88
  • @user1766548 if you didn't understand that code, then how are you going to understand any other code that we post here? – Kiril Oct 22 '12 at 21:19
  • 1
    this project was marked as a duplicate by a guy who got downvoted for his answer...... nice – John Demetriou May 24 '13 at 21:01
  • The answer in the duplicate is a good one. Go there. – CAD bloke Jun 05 '13 at 00:48
  • 2
    @CADbloke the answer I needed has already been accepted as an answer. This question was marked as a duplicate by a guy who's answered was downvoted because it did not fit my needs. People who also mark something as duplicate do not check what it is. They just accept it and go on with their lives without checking it – John Demetriou Jun 05 '13 at 07:28
  • Normally when a question is marked as a duplicate there's a link to the duplicate question, but I can't see that here. Where is the duplicate question? – markshep Mar 11 '15 at 12:55
  • @markshep look at the last comment I made :D anyways. One of the answers here is the answer in the duplicate – John Demetriou Mar 11 '15 at 16:59

3 Answers3

12

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).

Blake
  • 2,357
  • 3
  • 25
  • 35
  • i will try this tommorrow and let you know the results, I am currently going to sleep as I am too tired from failed tries :D – John Demetriou Oct 22 '12 at 23:33
  • Do you mean you want to change the directory where your executable is deployed? Also, what string manipulation do you want to avoid? – Blake Oct 23 '12 at 14:48
  • never mind, i used your code, it really helped, i answered my follow up questions myself – John Demetriou Oct 26 '12 at 17:23
  • great! glad it worked out for you. if the answer helped, please upvote it (click the arrow above the number in the question). would appreciate it - thanks :) – Blake Oct 26 '12 at 18:58
  • i couldn't due to too low reputation, but i did now – John Demetriou Oct 27 '12 at 16:22
  • 1
    @user2781812 This is how it should be done. This question was marked as a duplicate of another one but the other one's answer was not as good as this one. Highly recommend this version – John Demetriou Jan 21 '15 at 12:44
9

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();
Community
  • 1
  • 1
viggity
  • 15,039
  • 7
  • 88
  • 96
  • 1
    Doesn't give a correct path for `Uri uri2 = new Uri(@"c:\foo\bar\bazz");` – L.B Oct 22 '12 at 20:41
  • @viggity it is not an exact duplicate of no question, the answer that i want was blake's anser. The answer you thought i needed was not working – John Demetriou Oct 26 '12 at 17:26
  • 1
    @L.B If bazz is a directory, use `Uri uri2 = new Uri(@"c:\foo\bar\bazz\");` If bazz is a file then it is correct. – Tom Blodget Mar 17 '15 at 18:26
  • did work for me, just needed to switch slashes to backslashes after `ToString()` – dba Sep 16 '22 at 09:20
0

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? ;)

Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
  • Yes, all I want of it is to work. I posted this comment to the solution above C:/Users/JPD/Desktop/project/Resources/images/image1.jpeg but if i move the folder somewhere else for example in a folder called projects in my documents folder i want my code to still find that image, is the solution you gave me gonna fix that??? Will your solution work???? – John Demetriou Oct 22 '12 at 21:12
  • @user1766548 Kindly view the edition to my answer. As for your question - yes it will work **if** I understood your issue correctly. – Konrad Viltersten Oct 22 '12 at 21:18
  • I will try it and let you know, thanks for your help – John Demetriou Oct 22 '12 at 21:23
  • your solution did not work...... – John Demetriou Oct 22 '12 at 22:23
  • to be more specific 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???? – John Demetriou Oct 22 '12 at 22:54
  • @macrian Ah, now I see. Check my edit. This is what you need. You might want to adapt the variables `deletableTarget` and `hereWeAre` so that the message box right after their declaration shows the exactly right path but that's something you'll manage easily, I'm sure. Good luck and don't forget to vote/check as answered the reply that **you** find the most helpful. – Konrad Viltersten Oct 23 '12 at 04:33
  • your new answer is as helpful as blake's, this is what i wanted all along, just my english is a little bad and phrase it correctly – John Demetriou Oct 23 '12 at 11:51
  • I also have a question for you. What does the @ operator do in your code?? if the string is stored in a string object is it needed????? or is it only needed when it's a preceding an explicit string??? – John Demetriou Oct 23 '12 at 12:50
  • @macrian Why don't you ask Blake, haha. Naa, just kidding. The AT-operator lets the compiler know that the string you're providing is to be interpreted in verbatim mode, meaning that e.x. "\n" is not a line break but a backslash and the letter n. Backslash character ("\") is an escape character, meaning it has a special meaning. E.g. "\t" is "tab" and "\u1234" is a unicode character. So, you can go @"c:\" or "c:\\" but you can't go "c:\" in C#. – Konrad Viltersten Oct 23 '12 at 14:49
  • oh ok, i know about the escape characters and backslash (that is what i am using double backslash) i didn't know it could be done using @, thanks mate – John Demetriou Oct 23 '12 at 18:23
  • @macrian It looks nicer when you have the verbatim version. It's especially in handy when you're creating a hard-coded string for a XML. You can then keep the structure of the contents visually appealing to human eye **without** breaking up the string and using a plus sign to concatenate the parts. Vote Blake up if you liked his answer so he'll get some extra reputation. Always a nice gesture on your part. :) – Konrad Viltersten Oct 24 '12 at 07:18
  • i am not allowed to vote up until i get 15 reputation :D – John Demetriou Oct 26 '12 at 17:23
  • @macrian Now you are! ;) – Konrad Viltersten Oct 26 '12 at 17:46