Relative File Names (how to call them from anywhere?)

Started by
12 comments, last by leiavoia 18 years, 1 month ago
A classic problem i'm sure. ISSUE #1: I'm have my program located here: c:/foo/bar/SomeProgram.exe SomeProgram.exe contains code that look something like this: . . . resource = LoadResource("dir/some_file.bla"); // relative file name . . . So if we run SomeProgram.exe from the command line in the directory it resides in, the program will find some_file, like so: (change directory to the program directory) cd c:/foo/bar/ (run app) ./SomeProgram.exe (app finds file at ...) c:/foo/bar/dir/some_file.bla Hey, works great. Until i try to run the app from somewhere else. I change my working directory to some arbitrary directory *or* click an icon from the desktop, my app can't find it's dependent files. How do i get an app to find files it needs in a specific location without knowing where it's installed? How do other programmer solve this? Bonus question: will the same strategy work on windows and unix? ISSUE #2: (Related problem) I have a library @ /some/dir/libSomeLib I run a program that uses the library, located @ /foo/bar/SomeProgram.exe When i run the program, it would seem that relative file names in libSomeLib now base off of /foo/bar (the app's directory) and not /some/dir (the lib's directory)! How do i get libSomeLib to "stay in it's own directory"? (ps - i wrote the app and the lib both) Thanks for your help. I'm sure this is an easy question. It's just one i never got around to answering. Thanks!
Advertisement
What programming language are you using? What operating system?

In windows, you can use the GetModuleName API function to retrieve the full path and file name of an executable or dll. You'll have to split it apart yourself and append the relative path, though. If you just want to tack on the current directory, you can use GetFullPathName
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
For issue #1, you shouldn't write your program to try and find the resources it needs if they've been purposely moved elsewhere by the user; your program should just assume the resources will be in the same directory, because otherwise it's the user's fault for moving things around. Plus, to account for such a thing would require you to write some search algorithm that scanned the users entire system, which even then you're not guaranteed to find the resource.

For issue #2... not sure why you're getting that problem....
There are methods for determining in which directory the currently loaded module is executed; for Windows, such method is GetModuleFileName (I don't remember the equivalent for Unix). To get the path from the full path + filename string, just split the string before it's last "\" (again, in Windows) or "/" (in Unix).

You shouldn't rely on "cd" in multi-process environments, as any other app or even your own file accesses can change the current directory without you getting any warning.

EDIT: Too late [grin]

Niko Suni

I'm using C++

I need it on both linux and windows. Mostly linux at the moment, but i intend to release my project on windows as well. I'm developing on linux.

I'm assuming i have to call some kind of system call like WhereAmI() and parse the string, correct?

EDIT: jeez you guys are fast! you just stay up late at night waiting to pounce on new threads don't you? :-)
Quote:Original post by Nik02You shouldn't rely on "cd" in multi-process environments, as any other app or even your own file accesses can change the current directory without you getting any warning.


That was just an example. That isn't code the app runs. That's me running the app from the command line.
Quote:Original post by leiavoia
Quote:Original post by Nik02You shouldn't rely on "cd" in multi-process environments, as any other app or even your own file accesses can change the current directory without you getting any warning.


That was just an example. That isn't code the app runs. That's me running the app from the command line.


Yes, but it doesn't matter if you change it manually or programmatically. In either case, some other process can change it again even before you run your program in the next command.

Niko Suni

Maybe i'm not wording this correctly. The above example is me in a console / DOS prompt changing to the correct directory and then executing the program. It has nothing to do with code.

$ cd /some/dir
$ ./some_app.exe
(program runs)

Because that's usually how i "start" my programs. I don't click on a link or icon or something because then it doesn't work right.

Did i explain it better?
It would appear that full pathnames are basically the way to go on unix systems:

Quote: from http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC23
The most common reason people ask this question is in order to locate configuration files with their program. This is considered to be bad form; directories containing executables should contain nothing except executables, and administrative requirements often make it desirable for configuration files to be located on different filesystems to executables.


That's good for unix, but most windows games i played in years past usually come in one big lump with no installation (especially freebie games that you just unzip and run).

Would you agree? What should my approach on a windows system be? I prefer the "one big lump" technique, but that's just me with my unenlightened viewpoint.
Yes, if you plan to really distribute your app on linux, then installation will not place your binary together with your data and configuration files.

Plan on it from the beginning, it can be a mess with all sorts of filenames embedded in .cpp files. If you package as a .rpm or .deb then your program probably ends up in /usr/bin, while if you have a tar.gz then it probably ends in /usr/local/bin. Make a hidden directory or file to store user-specific configuration files in the users home directory.

This topic is closed to new replies.

Advertisement