Return the root directory of Delphi executable
Asked Answered
C

4

8

I have a Delphi application executing and when I call GetCurrentDir the following returns:

C:\dev\w32\2015\BCSLBDemo\Win32\Debug

When I call ExtractFileDir(GetCurrentDir()) I receive the following:

C:\dev\w32\2015\BCSLBDemo\Win32

What I desire is C:\dev\w32\2015\BCSLBDemo

function RetRoot: string;
var
  i: Integer;
  buf: string;
begin
  Result := '';
  buf := ExtractFileDir(GetCurrentDir());
  i := Length(buf);
  repeat
    dec(i);
  until (buf[i] = '\') or (i < 3);
  if buf[i] = '\' then
  begin
    Delete(buf, i, Length(buf));
    Result := buf;
  end;
end;

I wrote this function to get the desired result. I would like to know if there is a better approach to accomplish retrieving the root directory of a Delphi executable.

Celestaceleste answered 30/9, 2015 at 15:22 Comment(7)
I suppose you need to define what you mean by the root directory of a Delphi executable. Suppose you copy the executable to a folder under the program files directory, as you would if you installed it. What would be the root directory. FWIW, the current directory is only coincidentally the same directory as the executable is in. It does not have to be. Your text processing code is very needless. You can delete it all and replace with standard function calls.Grotesquery
So, you might write ExtractFileDir(ParamStr(0)) to get the directory containing the executable. And to step up two directories ExtractFileDir(ExtractFileDir(ExtractFileDir(ParamStr(0)))). But why would you want to step up two directories? That seems plain weird. If you want better help, then you should explain what you are going to do with this information.Grotesquery
David I believe I know how to do these things. Your response was outstanding. I have not had the time to look into your offering further due to continual fire calls. Where is the documentation explaining the things you mention? Thanks ArchCelestaceleste
"C:\dev\w32\2015\BCSLBDemo\Win32\Debug ... What I desire is C:\dev\w32\2015\BCSLBDemo" - why? BCSLBDemo is your project root, not your executable root. Your executable is running from the Win32\Debug folder, because that is where the project is configured to output the executable that it creates. The executable has no concept of the project. So what are you really trying to accomplish by having the executable find the project root? What is it going to do with that path?Reputable
I need a location to load a control from a text file. When I place the zip on Embarcadero Code Central I never include the 32 bit nor the 64 bit executable directories. Therefore that text file needs a home other than the executable's root. Options are later made available to update that text file. This approach eliminates the need to recompile the application due to file content modification.Celestaceleste
You have clearly got the wrong solution in that case. Possible choices would be the same directory as executable, or a directory under the application data or program data folders.Grotesquery
There is no such thing as "root directory of a Delphi executable". Your desired dir is ..\..Schram
T
15

There's another way:

ExpandFileName(GetCurrentDir + '\..\..\'); // Current folder
ExpandFileName(ExtractFileDir(Application.ExeName) + '\..\..\'); // Exe folder

C:\dev\w32\2015\BCSLBDemo

Will take you two levels up as you can see.

Of course this only answer the "how to get 2 levels up" question. The question about Exe root is kind of non-sense. You might just need to configure your project settings to not make the Win32\Debug folders or move your data files into there ;-)

Trutko answered 30/9, 2015 at 18:13 Comment(0)
Q
15

You can obtain the full path to an application executable using:

ParamStr(0);

For a form based application, you have also the Application object available:

Application.ExeName;

To get the path to the file without the file name, you may consider to use ExtractFileDir or ExtractFilePath.

The difference between the two is that ExtractFilePath retuns the path with the last delimiter (/ or \) and ExtractFileDir truncates it.


As stated in the David Heffernan's comment, multiple calls to ExtractFileDir allow to get the parent directory:

Having C:\dev\w32\2015\BCSLBDemo\Win32\Debug\Project1.exe you can obtain C:\dev\w32\2015\BCSLBDemo like this:

ExtractFileDir(ExtractFileDir(ExtractFileDir(ParamStr(0))));
Quetzal answered 30/9, 2015 at 15:29 Comment(5)
Do you know how Application.ExeName is implemented? It is ParamStr(0). So why make the distinction?Grotesquery
@DavidHeffernan answer modified O:-)Quetzal
Did you read the part of the question that said, What I desire is “C:\dev\w32\2015\BCSLBDemo”? Did you read my comments above?Grotesquery
@DavidHeffernan yes but the multiple calls to ExtractFileDir are already stated in your comment...Quetzal
Important: Application.ExeName only exists in VCL applications at the moment.Sid
T
15

There's another way:

ExpandFileName(GetCurrentDir + '\..\..\'); // Current folder
ExpandFileName(ExtractFileDir(Application.ExeName) + '\..\..\'); // Exe folder

C:\dev\w32\2015\BCSLBDemo

Will take you two levels up as you can see.

Of course this only answer the "how to get 2 levels up" question. The question about Exe root is kind of non-sense. You might just need to configure your project settings to not make the Win32\Debug folders or move your data files into there ;-)

Trutko answered 30/9, 2015 at 18:13 Comment(0)
D
1

You can obtain the full path to an application executable using:

Delphi 2010 declare Uses SWSystem;

Delphi Xe declare Uses IWSystem ;

showmessage(gsAppPath);

Dodge answered 25/5, 2017 at 19:8 Comment(0)
R
1

you can use $(RUN) (Runtime Variable) :

function Get_AppPath: string;
begin
  Result := ExtractFilePath(TPath.GetFullPath('$(RUN)'));
end;
Rolling answered 28/3, 2022 at 2:48 Comment(1)
I'm afraid this returns the CWD of the current process, not the path to the executable running. So it might be different depending on the directory you invoke the executable from.Creature

© 2022 - 2024 — McMap. All rights reserved.