www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Finding the path to a executable?

reply "Alan" <alanpotteiger gmail.com> writes:
Hello!  This may seem like a simple question, maybe an 
embarassing question but how would I fetch the absolute path to 
the directory where my executable is located?  My wording is 
known to be confusing so I will give an example:

cd ~/projects/program
dmd Program.d -ofProgram

That executable would be located in /home/alan/projects/program 
for example.  SO my question is how would I fetch the absolute 
path to that directory?

Thanks for any help!
Aug 06 2013
next sibling parent "Andre Artus" <andre.artus gmail.com> writes:
On Wednesday, 7 August 2013 at 05:31:24 UTC, Alan wrote:
 Hello!  This may seem like a simple question, maybe an 
 embarassing question but how would I fetch the absolute path to 
 the directory where my executable is located?  My wording is 
 known to be confusing so I will give an example:

 cd ~/projects/program
 dmd Program.d -ofProgram

 That executable would be located in /home/alan/projects/program 
 for example.  SO my question is how would I fetch the absolute 
 path to that directory?

 Thanks for any help!

Is this what you are looking for? find ~/projects/program/ -type f -perm +111 or ls -d -1 ~/projects/program/*
Aug 06 2013
prev sibling next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 08/06/2013 10:31 PM, Alan wrote:
 Hello!  This may seem like a simple question, maybe an embarassing
 question but how would I fetch the absolute path to the directory where
 my executable is located?  My wording is known to be confusing so I will
 give an example:

 cd ~/projects/program
 dmd Program.d -ofProgram

 That executable would be located in /home/alan/projects/program for
 example.  SO my question is how would I fetch the absolute path to that
 directory?

 Thanks for any help!

First program argument is the absolute path to the executable. (I am not sure whether this is portable.) import std.stdio; import std.path; void main(string[] args) { writefln("I am program '%s' in '%s'.", baseName(args[0]), dirName(args[0])); } Ali
Aug 06 2013
prev sibling next sibling parent "Alan" <alanpotteiger gmail.com> writes:
On Wednesday, 7 August 2013 at 06:08:44 UTC, Andre Artus wrote:
 On Wednesday, 7 August 2013 at 05:31:24 UTC, Alan wrote:
 Hello!  This may seem like a simple question, maybe an 
 embarassing question but how would I fetch the absolute path 
 to the directory where my executable is located?  My wording 
 is known to be confusing so I will give an example:

 cd ~/projects/program
 dmd Program.d -ofProgram

 That executable would be located in 
 /home/alan/projects/program for example.  SO my question is 
 how would I fetch the absolute path to that directory?

 Thanks for any help!

Is this what you are looking for? find ~/projects/program/ -type f -perm +111 or ls -d -1 ~/projects/program/*

No sorry, I meant how to find the directory in D code.
Aug 06 2013
prev sibling next sibling parent reply "evilrat" <evilrat666 gmail.com> writes:
On Wednesday, 7 August 2013 at 05:31:24 UTC, Alan wrote:
 Hello!  This may seem like a simple question, maybe an 
 embarassing question but how would I fetch the absolute path to 
 the directory where my executable is located?  My wording is 
 known to be confusing so I will give an example:

 cd ~/projects/program
 dmd Program.d -ofProgram

 That executable would be located in /home/alan/projects/program 
 for example.  SO my question is how would I fetch the absolute 
 path to that directory?

 Thanks for any help!

you mean absolute path at runtime? this is passed as args[0] in main(string[] args). though it contains not path but string used to launch ur program( for example "./program" when launched from its location, and full program path when double-clicked). also you can use getcwd() from std.path. but you can't rely on it as both of this takes "caller" location. may be this helps you : http://msdn.microsoft.com/en-us/library/ms683197(VS.85).aspx http://man7.org/linux/man-pages/man3/getcwd.3.html p.s. such question better ask in learn section
Aug 06 2013
parent Manfred Nowak <svv1999 hotmail.com> writes:
evilrat wrote:
 in theory should always return actual program path

Which theory? Especially in heteromorphic systems there is no such thing like a unique path between two accessible "points" in a file system. -manfred
Aug 07 2013
prev sibling next sibling parent "Alan" <alanpotteiger gmail.com> writes:
On Wednesday, 7 August 2013 at 06:10:16 UTC, Ali Çehreli wrote:
 On 08/06/2013 10:31 PM, Alan wrote:
 Hello!  This may seem like a simple question, maybe an 
 embarassing
 question but how would I fetch the absolute path to the 
 directory where
 my executable is located?  My wording is known to be confusing 
 so I will
 give an example:

 cd ~/projects/program
 dmd Program.d -ofProgram

 That executable would be located in 
 /home/alan/projects/program for
 example.  SO my question is how would I fetch the absolute 
 path to that
 directory?

 Thanks for any help!

First program argument is the absolute path to the executable. (I am not sure whether this is portable.) import std.stdio; import std.path; void main(string[] args) { writefln("I am program '%s' in '%s'.", baseName(args[0]), dirName(args[0])); } Ali

Just missed your response! And no that doesn't fetch the absolute path, just the relative path. Thanks for help so far though!
Aug 06 2013
prev sibling next sibling parent "Alan" <alanpotteiger gmail.com> writes:
On Wednesday, 7 August 2013 at 06:13:59 UTC, evilrat wrote:
 On Wednesday, 7 August 2013 at 05:31:24 UTC, Alan wrote:
 Hello!  This may seem like a simple question, maybe an 
 embarassing question but how would I fetch the absolute path 
 to the directory where my executable is located?  My wording 
 is known to be confusing so I will give an example:

 cd ~/projects/program
 dmd Program.d -ofProgram

 That executable would be located in 
 /home/alan/projects/program for example.  SO my question is 
 how would I fetch the absolute path to that directory?

 Thanks for any help!

you mean absolute path at runtime? this is passed as args[0] in main(string[] args). though it contains not path but string used to launch ur program( for example "./program" when launched from its location, and full program path when double-clicked). also you can use getcwd() from std.path. but you can't rely on it as both of this takes "caller" location. may be this helps you : http://msdn.microsoft.com/en-us/library/ms683197(VS.85).aspx http://man7.org/linux/man-pages/man3/getcwd.3.html p.s. such question better ask in learn section

Sorry about the section mishap, I'm new here! Believe me I have tried all sorts of combonations of this but it's not guarunteed accuracy in certain situations, I thought there would be a solution in phobos library I was missing but maybe I will have to write something complex out. Thanks for all the help so far!
Aug 06 2013
prev sibling next sibling parent "evilrat" <evilrat666 gmail.com> writes:
On Wednesday, 7 August 2013 at 06:10:16 UTC, Ali Çehreli wrote:
 First program argument is the absolute path to the executable. 
 (I am not sure whether this is portable.)

 import std.stdio;
 import std.path;

 void main(string[] args)
 {
     writefln("I am program '%s' in '%s'.",
              baseName(args[0]), dirName(args[0]));
 }

 Ali

the problem with this that its not absolute path, it is whatever string you started your app, i.e. lets assume ~/location/program is executable, and we call it -- cd ~/location cd ../ ./location/prog --- args[0] would contaion ./location/prog but combine it with cwd and this would be (always?) the exact program path
Aug 06 2013
prev sibling next sibling parent "evilrat" <evilrat666 gmail.com> writes:
On Wednesday, 7 August 2013 at 06:18:26 UTC, Alan wrote:
 Believe me I have tried all sorts of combonations of this but 
 it's not guarunteed accuracy in certain situations, I thought 
 there would be a solution in phobos library I was missing but 
 maybe I will have to write something complex out.
 Thanks for all the help so far!

putting all together try this(not tested) import std.path; void main(string[] args) { writeln(absolutePath(buildNormalizedPath(args[0]))); }
Aug 06 2013
prev sibling next sibling parent "Andre Artus" <andre.artus gmail.com> writes:
On Wednesday, 7 August 2013 at 06:10:35 UTC, Alan wrote:
 On Wednesday, 7 August 2013 at 06:08:44 UTC, Andre Artus wrote:
 On Wednesday, 7 August 2013 at 05:31:24 UTC, Alan wrote:
 Hello!  This may seem like a simple question, maybe an 
 embarassing question but how would I fetch the absolute path 
 to the directory where my executable is located?  My wording 
 is known to be confusing so I will give an example:

 cd ~/projects/program
 dmd Program.d -ofProgram

 That executable would be located in 
 /home/alan/projects/program for example.  SO my question is 
 how would I fetch the absolute path to that directory?

 Thanks for any help!

Is this what you are looking for? find ~/projects/program/ -type f -perm +111 or ls -d -1 ~/projects/program/*

No sorry, I meant how to find the directory in D code.

Sorry, I misunderstood.
Aug 06 2013
prev sibling next sibling parent "Alan" <alanpotteiger gmail.com> writes:
On Wednesday, 7 August 2013 at 06:25:26 UTC, Andre Artus wrote:
 On Wednesday, 7 August 2013 at 06:10:35 UTC, Alan wrote:
 On Wednesday, 7 August 2013 at 06:08:44 UTC, Andre Artus wrote:
 On Wednesday, 7 August 2013 at 05:31:24 UTC, Alan wrote:
 Hello!  This may seem like a simple question, maybe an 
 embarassing question but how would I fetch the absolute path 
 to the directory where my executable is located?  My wording 
 is known to be confusing so I will give an example:

 cd ~/projects/program
 dmd Program.d -ofProgram

 That executable would be located in 
 /home/alan/projects/program for example.  SO my question is 
 how would I fetch the absolute path to that directory?

 Thanks for any help!

Is this what you are looking for? find ~/projects/program/ -type f -perm +111 or ls -d -1 ~/projects/program/*

No sorry, I meant how to find the directory in D code.

Sorry, I misunderstood.

You're fine! Thanks for trying though!
Aug 06 2013
prev sibling next sibling parent "Andre Artus" <andre.artus gmail.com> writes:
On Wednesday, 7 August 2013 at 06:22:25 UTC, evilrat wrote:
 On Wednesday, 7 August 2013 at 06:18:26 UTC, Alan wrote:
 Believe me I have tried all sorts of combonations of this but 
 it's not guarunteed accuracy in certain situations, I thought 
 there would be a solution in phobos library I was missing but 
 maybe I will have to write something complex out.
 Thanks for all the help so far!

putting all together try this(not tested) import std.path;

import std.stdio;
 void main(string[] args)
 {
 writeln(absolutePath(buildNormalizedPath(args[0])));
 }

Works for me.
Aug 06 2013
prev sibling next sibling parent "Alan" <alanpotteiger gmail.com> writes:
On Wednesday, 7 August 2013 at 06:22:25 UTC, evilrat wrote:
 On Wednesday, 7 August 2013 at 06:18:26 UTC, Alan wrote:
 Believe me I have tried all sorts of combonations of this but 
 it's not guarunteed accuracy in certain situations, I thought 
 there would be a solution in phobos library I was missing but 
 maybe I will have to write something complex out.
 Thanks for all the help so far!

putting all together try this(not tested) import std.path; void main(string[] args) { writeln(absolutePath(buildNormalizedPath(args[0]))); }

I suppose that could work with a few modifications for consistency. THanks for the help everyone!
Aug 06 2013
prev sibling next sibling parent "Kapps" <opantm2+spam gmail.com> writes:
On Wednesday, 7 August 2013 at 05:31:24 UTC, Alan wrote:
 Hello!  This may seem like a simple question, maybe an 
 embarassing question but how would I fetch the absolute path to 
 the directory where my executable is located?  My wording is 
 known to be confusing so I will give an example:

 cd ~/projects/program
 dmd Program.d -ofProgram

 That executable would be located in /home/alan/projects/program 
 for example.  SO my question is how would I fetch the absolute 
 path to that directory?

 Thanks for any help!

The approach that I use is http://pastie.org/8214264 - The implementation probably has a fair few flaws though in regards to buffer sizes (and only supports Windows / Linux). It's worked in the basic situations I've tried though.
Aug 06 2013
prev sibling next sibling parent "Kapps" <opantm2+spam gmail.com> writes:
On Wednesday, 7 August 2013 at 06:22:25 UTC, evilrat wrote:
 On Wednesday, 7 August 2013 at 06:18:26 UTC, Alan wrote:
 Believe me I have tried all sorts of combonations of this but 
 it's not guarunteed accuracy in certain situations, I thought 
 there would be a solution in phobos library I was missing but 
 maybe I will have to write something complex out.
 Thanks for all the help so far!

putting all together try this(not tested) import std.path; void main(string[] args) { writeln(absolutePath(buildNormalizedPath(args[0]))); }

I'd imagine (but I could be mistaken here) that that uses the current working directory as the base. I've had issues with this in the old std.path where the CWD is different from the program when starting it up (possibly related to shortcuts, or perhaps just the IDE setting it manually).
Aug 06 2013
prev sibling next sibling parent "evilrat" <evilrat666 gmail.com> writes:
On Wednesday, 7 August 2013 at 06:38:29 UTC, Kapps wrote:
 On Wednesday, 7 August 2013 at 06:22:25 UTC, evilrat wrote:
 On Wednesday, 7 August 2013 at 06:18:26 UTC, Alan wrote:
 Believe me I have tried all sorts of combonations of this but 
 it's not guarunteed accuracy in certain situations, I thought 
 there would be a solution in phobos library I was missing but 
 maybe I will have to write something complex out.
 Thanks for all the help so far!

putting all together try this(not tested) import std.path; void main(string[] args) { writeln(absolutePath(buildNormalizedPath(args[0]))); }

I'd imagine (but I could be mistaken here) that that uses the current working directory as the base. I've had issues with this in the old std.path where the CWD is different from the program when starting it up (possibly related to shortcuts, or perhaps just the IDE setting it manually).

yes it probably may return wrong path when messed up with setcwd, but when taken at startup this in theory should always return actual program path.
Aug 06 2013
prev sibling next sibling parent "Tommi" <tommitissari hotmail.com> writes:
On Wednesday, 7 August 2013 at 05:31:24 UTC, Alan wrote:
 Hello!  This may seem like a simple question, maybe an 
 embarassing question but how would I fetch the absolute path to 
 the directory where my executable is located?  My wording is 
 known to be confusing so I will give an example:

 cd ~/projects/program
 dmd Program.d -ofProgram

 That executable would be located in /home/alan/projects/program 
 for example.  SO my question is how would I fetch the absolute 
 path to that directory?

 Thanks for any help!

This should work on at least couple of systems, but I haven't tested this on other than Mac. Also, it's not completely robust, because paths could be longer than 4096 chars. version(Windows) { import std.c.windows.windows; } else version(OSX) { private extern(C) int _NSGetExecutablePath(char* buf, uint* bufsize); } else version(linux) { import std.c.linux.linux; } else { static assert(0); } import std.conv; // Returns the full path to the currently running executable string executablePath() { static string cachedExecutablePath; if (!cachedExecutablePath) { char[4096] buf; uint filePathLength; version(Windows) { filePathLength = GetModuleFileNameA(null, buf.ptr, buf.length - 1); assert(filePathLength != 0); } else version(OSX) { filePathLength = cast(uint) (buf.length - 1); int res = _NSGetExecutablePath(buf.ptr, &filePathLength); assert(res == 0); } else version(linux) { filePathLength = readlink(toStringz(selfExeLink), buf.ptr, buf.length - 1); } else { static assert(0); } cachedExecutablePath = to!string(buf[0 .. filePathLength]); } return cachedExecutablePath; } // Returns the file name of the currently running executable string executableName() { return executablePath().baseName(); } // Returns the path to the directory of the currently running executable string executableDirPath() { return executablePath().dirName(); }
Aug 07 2013
prev sibling next sibling parent "Tommi" <tommitissari hotmail.com> writes:
...sorry, add import std.path; if you need the last two functions.
Aug 07 2013
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-08-07 07:31, Alan wrote:
 Hello!  This may seem like a simple question, maybe an embarassing
 question but how would I fetch the absolute path to the directory where
 my executable is located?  My wording is known to be confusing so I will
 give an example:

 cd ~/projects/program
 dmd Program.d -ofProgram

 That executable would be located in /home/alan/projects/program for
 example.  SO my question is how would I fetch the absolute path to that
 directory?

 Thanks for any help!

There's a pull request for that: https://github.com/D-Programming-Language/phobos/pull/1224 -- /Jacob Carlborg
Aug 07 2013
prev sibling next sibling parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On Wed, 07 Aug 2013 09:13:03 +0200
"Tommi" <tommitissari hotmail.com> wrote:

 On Wednesday, 7 August 2013 at 05:31:24 UTC, Alan wrote:
 Hello!  This may seem like a simple question, maybe an 
 embarassing question but how would I fetch the absolute path to 
 the directory where my executable is located?  My wording is 
 known to be confusing so I will give an example:

 cd ~/projects/program
 dmd Program.d -ofProgram

 That executable would be located in /home/alan/projects/program 
 for example.  SO my question is how would I fetch the absolute 
 path to that directory?

 Thanks for any help!

This should work on at least couple of systems, but I haven't tested this on other than Mac. Also, it's not completely robust, because paths could be longer than 4096 chars. version(Windows) { import std.c.windows.windows; } else version(OSX) { private extern(C) int _NSGetExecutablePath(char* buf, uint* bufsize); } else version(linux) { import std.c.linux.linux; } else { static assert(0); } import std.conv; // Returns the full path to the currently running executable string executablePath() { static string cachedExecutablePath; if (!cachedExecutablePath) { char[4096] buf; uint filePathLength; version(Windows) { filePathLength = GetModuleFileNameA(null, buf.ptr, buf.length - 1); assert(filePathLength != 0); } else version(OSX) { filePathLength = cast(uint) (buf.length - 1); int res = _NSGetExecutablePath(buf.ptr, &filePathLength); assert(res == 0); } else version(linux) { filePathLength = readlink(toStringz(selfExeLink), buf.ptr, buf.length - 1); } else { static assert(0); } cachedExecutablePath = to!string(buf[0 .. filePathLength]); } return cachedExecutablePath; } // Returns the file name of the currently running executable string executableName() { return executablePath().baseName(); } // Returns the path to the directory of the currently running executable string executableDirPath() { return executablePath().dirName(); }

Yes, this is the way to do it. Never use args[0]: it's useless as it doesn't follow symlinks (might not even follow aliases, though I'm not certain), and strictly-speaking can't even be guaranteed to be correct at all anyway. If it were up to me, args[0] would be eliminated outright.
Aug 07 2013
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Aug 07, 2013 at 12:55:10PM -0400, Nick Sabalausky wrote:
 On Wed, 07 Aug 2013 09:13:03 +0200
 "Tommi" <tommitissari hotmail.com> wrote:
 
 On Wednesday, 7 August 2013 at 05:31:24 UTC, Alan wrote:
 Hello!  This may seem like a simple question, maybe an 
 embarassing question but how would I fetch the absolute path to 
 the directory where my executable is located?  My wording is 
 known to be confusing so I will give an example:

 cd ~/projects/program
 dmd Program.d -ofProgram

 That executable would be located in /home/alan/projects/program 
 for example.  SO my question is how would I fetch the absolute 
 path to that directory?

 Thanks for any help!

This should work on at least couple of systems, but I haven't tested this on other than Mac. Also, it's not completely robust, because paths could be longer than 4096 chars. version(Windows) { import std.c.windows.windows; } else version(OSX) { private extern(C) int _NSGetExecutablePath(char* buf, uint* bufsize); } else version(linux) { import std.c.linux.linux; } else { static assert(0); } import std.conv; // Returns the full path to the currently running executable string executablePath() { static string cachedExecutablePath; if (!cachedExecutablePath) { char[4096] buf; uint filePathLength; version(Windows) { filePathLength = GetModuleFileNameA(null, buf.ptr, buf.length - 1); assert(filePathLength != 0); } else version(OSX) { filePathLength = cast(uint) (buf.length - 1); int res = _NSGetExecutablePath(buf.ptr, &filePathLength); assert(res == 0); } else version(linux) { filePathLength = readlink(toStringz(selfExeLink), buf.ptr, buf.length - 1); } else { static assert(0); } cachedExecutablePath = to!string(buf[0 .. filePathLength]); } return cachedExecutablePath; } // Returns the file name of the currently running executable string executableName() { return executablePath().baseName(); } // Returns the path to the directory of the currently running executable string executableDirPath() { return executablePath().dirName(); }

Yes, this is the way to do it. Never use args[0]: it's useless as it doesn't follow symlinks (might not even follow aliases, though I'm not certain), and strictly-speaking can't even be guaranteed to be correct at all anyway.

+1. If you invoke your program from the shell, it will generally be correct (though unhelpful if the program was found through $PATH, because the shell only passes the bare program name in argv[0], not the full path, leaving you having to search through $PATH all over again -- and even then, there's no guarantee the shell wasn't configured NOT to pass $PATH along: some security models recommend not doing so). But if your program was invoked from another program, there's no guarantee at all what args[0] contains. For all you know, it could be "/path/to/rootkit/maliciousProgram.exe".
 If it were up to me, args[0] would be eliminated outright.

Naw, there are some valid use cases for it. Take a look at busybox, for example. :) T -- Не дорог подарок, дорога любовь.
Aug 07 2013
prev sibling next sibling parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On Wed, 7 Aug 2013 10:06:19 -0700
"H. S. Teoh" <hsteoh quickfur.ath.cx> wrote:

 On Wed, Aug 07, 2013 at 12:55:10PM -0400, Nick Sabalausky wrote:
 
 If it were up to me, args[0] would be eliminated outright.

Naw, there are some valid use cases for it. Take a look at busybox, for example. :)

Hmm, interesting tool. And you're right, I can't think of a better way than args[0] to do what it does. In any case, Phobos needs to have this "get current executable's path" function if it doesn't already.
Aug 10 2013
prev sibling parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On Sun, 11 Aug 2013 00:45:43 -0400
Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> wrote:

 On Wed, 7 Aug 2013 10:06:19 -0700
 "H. S. Teoh" <hsteoh quickfur.ath.cx> wrote:
 
 On Wed, Aug 07, 2013 at 12:55:10PM -0400, Nick Sabalausky wrote:
 
 If it were up to me, args[0] would be eliminated outright.

Naw, there are some valid use cases for it. Take a look at busybox, for example. :)

Hmm, interesting tool. And you're right, I can't think of a better way than args[0] to do what it does. In any case, Phobos needs to have this "get current executable's path" function if it doesn't already.

Pull request: https://github.com/D-Programming-Language/phobos/pull/1463 It's updated from an older version that I had in here: https://bitbucket.org/Abscissa/semitwistdtools/src/c7f89f7cd2c086591b544d5bffc536827ae6f763/src/semitwist/util/io.d?at=master#cl-190
Aug 10 2013