Recent

Author Topic: How can I get application directory?  (Read 29568 times)

luigi65

  • New Member
  • *
  • Posts: 24
    • http://www.lodevelop.org
How can I get application directory?
« on: February 16, 2009, 07:25:39 pm »
How can I get the current working directory of the application?

GetCurrentDir work fine if I run the application from IDE, but if I launch the application from the bundle file .app (after a compilation) then this function always return the root / directory.

There is a method to have the application directory that work also from bundle file?


Thanks & goodbye

luigi65

  • New Member
  • *
  • Posts: 24
    • http://www.lodevelop.org
Re: How can I get application directory?
« Reply #1 on: February 16, 2009, 07:55:20 pm »
I have found this solution:

Code: [Select]
  g_path := ExtractFilePath(Application.ExeName);
  {$IFDEF DARWIN}
  g_path := LeftStr(g_path, Pos('myapp.app', g_path)-1);
  {$ENDIF}

so in g_path I have the application directory, also if I run from bundle file.

There is a better solution?


Jaco

  • New Member
  • *
  • Posts: 45
Re: How can I get application directory?
« Reply #2 on: February 16, 2009, 07:57:19 pm »
Hi,

What I use are the following function:

Getinstalldir gives you what it is: the path to the executable.
Getbasedir gives you the path to the bundle (Mac), or just the same as getinstalldir for Win.

Hope this helps you out.

Jaco


function slash(value:string):string;
begin
if (value='') then result:=''
              else begin
                   {$IFDEF WINDOWS}
                   if (value[length(value)]<>'\') then result:=value+'\'
                   {$ELSE}
                   if (value[length(value)]<>'/') then result:=value+'/'
                   {$ENDIF}
                                                  else result:=value;
                   end;
end;

function getinstalldir:string;
begin
result:=slash(extractfiledir(paramstr(0)));
end;

function getbasedir:string;
Begin
{$IFDEF WINDOWS}
result:=getinstalldir;
{$ELSE}
result:=copy(getinstalldir,1,pos(extractfilename(paramstr(0))+'.app/Contents/MacOS',getinstalldir)-1);
{$ENDIF}
end;


Vincent Snijders

  • Administrator
  • Hero Member
  • *
  • Posts: 2661
    • My Lazarus wiki user page
Re: How can I get application directory?
« Reply #3 on: February 16, 2009, 08:03:10 pm »
Instead of the function slash, you can use AppendPathDelim.

Phil

  • Hero Member
  • *****
  • Posts: 2750
Re: How can I get application directory?
« Reply #4 on: February 16, 2009, 10:15:03 pm »
Some confusion and misinformation here:

Luigi: From a terminal command line in your project's folder, start your app like this:

open myapp.app

That should give the same results for GetCurrentDir as double-clicking the .app in Finder. Not sure why you're always seeing / with GetCurrentDir when the app is launched from the Laz IDE. Maybe there's a problem there with how it's launching the app.

Not sure what you mean by "working directory". Normally this is a synonum for "current directory". If you mean the location of the .app, that's not what GetCurrentDir returns.

Why do you need to know that? An .app can be dragged and dropped anywhere in the file system, although typically it will be located under /Applications. So I'm not sure that knowing where it's located is something you would normally be using.

However, if do need to know that for some reason, don't use the supplied code. It won't work if the app bundle is named differently from its executable, which is common. For example "My Program.app" with "myprog" executable. You can just chop off the final 3 folder names, searching back from the end of ParamStr(0) for 3 occurences of PathDelim.

Also, remember that Laz creates your app bundle with a symlink in Contents/MacOs that points back to the actual executable in your project folder. You would never distribute or move an app bundle that's set up like that - it's only done so for convenience. Instead, you would delete the symlink and copy the executable file in its place.

Thanks.

-Phil

luigi65

  • New Member
  • *
  • Posts: 24
    • http://www.lodevelop.org
Re: How can I get application directory?
« Reply #5 on: February 17, 2009, 11:35:36 am »
Sorry for my misinformation, but I am a newbie in Mac OSX.
This is first time that I try to porting an application from Linux to OSX.

Thanks for your precious information.

I now understand that I have to substitute the symlink with the actual executable into .app file.

Excuse me if I'm not clear in my exposition, but GetCurrentDir return / if I launch the application as double-clicking the .app in Finder or as "open myapp.app" in terminal.
If I run from IDE GetCurrentDir return the path where is the executable file (e.g. /Developer/Projects/test).

Now, if I have some auxiliaries files that my executable must use then I put this files into Contents/MacOs of the bundle, is it right?


Thanks

Phil

  • Hero Member
  • *****
  • Posts: 2750
Re: How can I get application directory?
« Reply #6 on: February 17, 2009, 03:37:50 pm »
Take a look at the structure of other .app bundles on your system. Typically there's a Resources folder in the bundle for additional files. You can reference it from your app via a relative path from ParamStr(0).

Also, be sure to review the extensive Apple documentation on bundles. Essentially a bundle has a place for anything you could possible want to add, including local frameworks, localizations, compiled libraries, etc.

I assume you've looked at this (from this subtopic to the end is essential reading for anyone new to OS X programming):

http://wiki.lazarus.freepascal.org/OS_X_Programming_Tips#Adding_an_icon_to_your_app_bundle

Thanks.

-Phil

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 772
Re: How can I get application directory?
« Reply #7 on: February 17, 2009, 11:03:10 pm »
Sorry for my misinformation, but I am a newbie in Mac OSX.
This is first time that I try to porting an application from Linux to OSX.

You may want to read this information first then: http://developer.apple.com/documentation/Porting/Conceptual/PortingUnix/intro/chapter_1_section_1.html

Quote
Excuse me if I'm not clear in my exposition, but GetCurrentDir return / if I launch the application as double-clicking the .app in Finder or as "open myapp.app" in terminal.

That is normal and expected. You may want to read all messages titled "specifying the relative path to a file that is located in the same folder as the application bundle? " at http://lists.freepascal.org/lists/fpc-pascal/2009-February/thread.html (note that there are two separate threads).

Quote
Now, if I have some auxiliaries files that my executable must use then I put this files into Contents/MacOs of the bundle, is it right?

No, that is not correct. Where to put which files is described in the Introduction to Bundle Programming Guide, under "Anatomy of a Modern Bundle".

dusanx

  • New Member
  • *
  • Posts: 17
Re: How can I get application directory?
« Reply #8 on: February 18, 2009, 12:39:10 am »
ExtractFilePath(ParamStr(0));

Edit: and ExcludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)))+'/../../somefolder' works too.
« Last Edit: February 18, 2009, 12:42:17 am by dusanx »

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 772
Re: How can I get application directory?
« Reply #9 on: February 20, 2009, 12:10:17 am »
ExtractFilePath(ParamStr(0));

Edit: and ExcludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)))+'/../../somefolder' works too.

Paramstr(0) must only be used on Dos and Windows (and maybe OS/2). On all other platforms the results are unpredictable and it will not work as you expect (in the best case it will never work; in the worst case it will only fail under certain circumstances, resulting in hard-to-find bugs). Read the mailing list thread I quoted above for more information.

dusanx

  • New Member
  • *
  • Posts: 17
Re: How can I get application directory?
« Reply #10 on: February 25, 2009, 09:14:50 am »
ExtractFilePath(ParamStr(0));

Edit: and ExcludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)))+'/../../somefolder' works too.

Paramstr(0) must only be used on Dos and Windows (and maybe OS/2). On all other platforms the results are unpredictable and it will not work as you expect (in the best case it will never work; in the worst case it will only fail under certain circumstances, resulting in hard-to-find bugs). Read the mailing list thread I quoted above for more information.

Sorry because of late answer: It's weird, I just finished Win/Mac/Linux project that uses ParamStr(0) and I get proper path everywhere?  :-\

Leledumbo

  • Hero Member
  • *****
  • Posts: 8273
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: How can I get application directory?
« Reply #11 on: February 25, 2009, 10:24:00 am »
Quote
Sorry because of late answer: It's weird, I just finished Win/Mac/Linux project that uses ParamStr(0) and I get proper path everywhere?
Try it on symlinks.

dusanx

  • New Member
  • *
  • Posts: 17
Re: How can I get application directory?
« Reply #12 on: February 25, 2009, 10:32:31 am »
Makes sense, I did not used them and it worked.

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 772
Re: How can I get application directory?
« Reply #13 on: February 25, 2009, 11:18:40 pm »
ExtractFilePath(ParamStr(0));

Edit: and ExcludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)))+'/../../somefolder' works too.

Paramstr(0) must only be used on Dos and Windows (and maybe OS/2). On all other platforms the results are unpredictable and it will not work as you expect (in the best case it will never work; in the worst case it will only fail under certain circumstances, resulting in hard-to-find bugs). Read the mailing list thread I quoted above for more information.

Sorry because of late answer: It's weird, I just finished Win/Mac/Linux project that uses ParamStr(0) and I get proper path everywhere?  :-\

As I said: "in the worst case it will only fail under certain circumstances". Once more: please read the threads I mentioned earlier for the details. It contains several examples of cases where it will fail.

 

TinyPortal © 2005-2018