views:

124

answers:

4

If I have an executable called app.exe which is what I am coding in C#, how would I get files from a folder loaded in the same directory as the app.exe, using relative paths?

This throws an illegal characters in path exception.

string [ ] files = Directory.GetFiles ( "\Archive\*.zip" );

How would one do this in C#?

+9  A: 
string currentDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
string archiveFolder = Path.Combine(currentDirectory, "archive");
string[] files = Directory.GetFiles(archiveFolder, "*.zip");

The first parameter is the path. The second is the search pattern you want to use.

Anna Lear
Be warned that this is not relative to the executable, unless the current directory is also the directory of the executable. It is by default, but not always
Kieren Johnstone
@Kieren That's true. Often it's c:\windows\system32 if you kick it off from a scheduled task or a service (unless you change it). I updated my answer to reflect how to get the exe path.
Mikael Svenson
Adding to Kieren's comment : there's also things like OpenFileDialog and SaveFileDialog which can change the current directory at runtime. (if RestoreDirectory property is left at its default value of false).
Moe Sisko
Fair point. I updated my answer. @Moe: Good to know. I didn't know RestoreDirectory existed.
Anna Lear
+4  A: 

Write it like this:

string[] files = Directory.GetFiles(@".\Archive", "*.zip");

. is for relative to the folder where you started your exe, and @ to allow \ in the name.

When using filters, you pass it as a second parameter. You can also add a third parameter to specify if you want to search recursively for the pattern.

In order to get the folder where your .exe actually resides, use:

var executingPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
Mikael Svenson
.\ means relative to the current directory, I think?
Kieren Johnstone
A single dot (.) can stand in for the current directory. Two dots (..) mean the parent of the current directory.
Eric
Exactly, but the question is talking about relative to the executable, not the current directory..?
Kieren Johnstone
Updated my answer to specify the ., and where your exe resides.
Mikael Svenson
+6  A: 

To make sure you have the application's path (and not just the current directory), use this:

http://msdn.microsoft.com/en-us/library/system.diagnostics.process.getcurrentprocess.aspx

Now you have a Process object that represents the process that is running.

Then use Process.MainModule.FileName:

http://msdn.microsoft.com/en-us/library/system.diagnostics.processmodule.filename.aspx

Finally, use Path.GetDirectoryName to get the folder containing the .exe:

http://msdn.microsoft.com/en-us/library/system.io.path.getdirectoryname.aspx

So this is what you want:

string folder = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + @"\Archive\";
string filter = "*.zip";
string[] files = Directory.GetFiles(folder, filter);

(Notice that "\Archive\" from your question is now @"\Archive\": you need the @ so that the \ backslashes aren't interpreted as the start of an escape sequence)

Hope that helps!

Kieren Johnstone
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); is simpler imo.
Mikael Svenson
@Mikael, Agreed, will try to update this answer shortly
Kieren Johnstone
+2  A: 

As others have said, you can/should prepend the string with @ (though you could also just escape the backslashes), but what they glossed over (that is, didn't bring it up despite making a change related to it) was the fact that, as I recently discovered, using \ at the beginning of a pathname, without . to represent the current directory, refers to the root of the current directory tree.

C:\foo\bar>cd \
C:\>

versus

C:\foo\bar>cd .\
C:\foo\bar>

(Using . by itself has the same effect as using .\ by itself, from my experience. I don't know if there are any specific cases where they somehow would not mean the same thing.)

You could also just leave off the leading .\ , if you want.

C:\foo>cd bar
C:\foo\bar>

In fact, if you really wanted to, you don't even need to use backslashes. Forwardslashes work perfectly well! (Though a single / doesn't alias to the current drive root as \ does.)

C:\>cd foo/bar
C:\foo\bar>

You could even alternate them.

C:\>cd foo/bar\baz
C:\foo\bar\baz>

...I've really gone off-topic here, though, so feel free to ignore all this if you aren't interested.

JAB