On Monday, 18 June 2012 at 20:53:27 UTC, Nick Sabalausky wrote:
"Kapps" <[email protected]> wrote in message
news:[email protected]...
On Sunday, 17 June 2012 at 22:39:00 UTC, Stephen Jones wrote:
I recently switched from Eclipse to monoD and found that all
my code to images etc was invalid because getcwd returns the
directory that contains the main entry code in Eclipse, but
returns the directory that contains the executable in
MonoDevelop. Is there a universally consistent way of
accessing files?
As mentioned, it is not reliable to use the current working
directory for making a relative path absolute.
Right. "Current Working Directory" and "Directory of
Executable" should
never be confused:
- The working directory should be assumed to always be
different, as it's
whatever directory the user just happens to be in when they run
your
program.
- If you want to load files that are relative to the exe's
path, then you
need the directory of the executble. The working directory
won't help at
all. Note that args[0] is *not* good for this either, as that
gets screwed
up by symlinks and all sorts of other stuff. args[0] is
unreliable.
The approach I use is GetModuleFileNameA on Windows
(GetModuleFileNameA(null, Buffer.ptr, MAX_PATH)) and
readLinkPosix for /proc/self/exe on Linux
(readLinkPosix("/proc/self/exe", Buffer.ptr, Buffer.length)).
Yea, that's definitely the way to go. Here are ready-to-go
functions that
should handle that on Windows, Linux and OSX (untested on OSX
as I don't
have a working Mac, but theoretically *should* work):
https://bitbucket.org/Abscissa/semitwistdtools/src/8123e04b593c/src/semitwist/util/io.d#cl-168
(Ignore the commented out function - that's just a remenant
from the
D1/Tango days, I should probably just delete that.)
Use those functions like this:
// Assuming the exe is "C:\Foo\Bar\App.exe"
assert(getExec() == `C:\Foo\Bar\App.exe`);
assert(getExecName() == `App.exe`);
assert(getExecPath() == `C:\Foo\Bar\`);
You should be able to rip those functions right out of that
file and plop
them into any util module you have, just make sure you also
include these
import lines:
version(Win32)
import std.c.windows.windows;
else version(OSX)
private extern(C) int _NSGetExecutablePath(char* buf, uint*
bufsize);
else
import std.c.linux.linux;
That was what I was after. Thanks.