返回Delphi可执行文件的根目录。

7
我有一个执行的Delphi应用程序,并且当我调用GetCurrentDir时,会返回以下内容:

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

当我调用ExtractFileDir(GetCurrentDir())时,我收到以下内容:

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

我想要的是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;

我写了这个函数以获取所需的结果。我想知道是否有更好的方法来检索 Delphi 可执行文件的根目录。


2
我猜你需要定义Delphi可执行文件的根目录是什么意思。假设您将可执行文件复制到程序文件目录下的一个文件夹中,就像您安装它一样。根目录将是什么。顺便说一句,当前目录只是与可执行文件所在目录巧合相同。它不必是这样。您的文本处理代码非常不必要。您可以删除所有内容并替换为标准函数调用。 - David Heffernan
3
所以,你可以写ExtractFileDir(ParamStr(0))来获取包含可执行文件的目录。如果要上升两个目录,则可以使用ExtractFileDir(ExtractFileDir(ExtractFileDir(ParamStr(0))))。但是为什么要向上跨越两个目录?这似乎很奇怪。如果你想获得更好的帮助,那么你应该解释一下你将如何使用这些信息。 - David Heffernan
David,我相信我知道如何做这些事情。你的回复非常出色。由于不断的火警,我还没有时间进一步研究你的提供。你提到的东西在哪里有解释说明的文档?谢谢,Arch。 - Arch Brooks
7
C:\dev\w32\2015\BCSLBDemo\Win32\Debug ... What I desire is C:\dev\w32\2015\BCSLBDemo” - 为什么?BCSLBDemo是您的项目根目录,而不是您的可执行文件根目录。您的可执行文件正在从Win32\Debug文件夹运行,因为该项目已配置为输出它创建的可执行文件。可执行文件没有关于项目的概念。那么,您真正想通过让可执行文件找到项目根目录来实现什么目的?它将如何处理该路径? - Remy Lebeau
1
在这种情况下,你显然选错了解决方案。可能的选择是与可执行文件相同的目录,或者是应用程序数据或程序数据文件夹下的目录。 - David Heffernan
显示剩余2条评论
4个回答

15

还有另一种方法:

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

C:\dev\w32\2015\BCSLBDemo

这会让你向上跳两个级别,如你所见。

当然,这只回答了“如何向上跳两个级别”的问题。关于Exe根目录的问题有点毫无意义。你可能只需要配置项目设置,不要创建 Win32\Debug 文件夹或将数据文件移动到那里。;-)


14

您可以使用以下代码获取应用程序可执行文件的完整路径:

ParamStr(0);

对于基于表单的应用程序,您还可以使用Application对象:

Application.ExeName;

要获取文件路径而不包括文件名,您可以考虑使用ExtractFileDirExtractFilePath

两者之间的区别在于:ExtractFilePath返回带有最后一个分隔符(/\)的路径,而ExtractFileDir则截断它。


David Heffernan评论中所述,多次调用ExtractFileDir可以获取父目录:

C:\dev\w32\2015\BCSLBDemo\Win32\Debug\Project1.exe,您可以这样获得C:\dev\w32\2015\BCSLBDemo

ExtractFileDir(ExtractFileDir(ExtractFileDir(ParamStr(0))));

你知道 Application.ExeName 是如何实现的吗?它是 ParamStr(0)。那么为什么要区分呢? - David Heffernan
@DavidHeffernan的回答已经被修改了 O:-) - fantaghirocco
你有看到问题中说的那部分内容吗,即“我想要的是'C:\dev\w32\2015\BCSLBDemo'”吗?你有看过我上面的评论吗? - David Heffernan
@DavidHeffernan 是的,但是对 ExtractFileDir 的多次调用已经在你的评论中说明了... - fantaghirocco
1
重要提示:Application.ExeName 目前仅存在于 VCL 应用程序中。 - Roberto Novakosky

1
您可以使用$(RUN)(运行时变量):
function Get_AppPath: string;
begin
  Result := ExtractFilePath(TPath.GetFullPath('$(RUN)'));
end;

很抱歉,这将返回当前进程的CWD,而不是正在运行的可执行文件的路径。因此,它可能会因为从哪个目录调用可执行文件而有所不同。 - ThomasH

1
您可以使用以下方法获取应用程序可执行文件的完整路径:

Delphi 2010: 声明 Uses SWSystem;

Delphi Xe: 声明 Uses IWSystem;

showmessage(gsAppPath);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接